From b73967e9a0c1178bdb83dcf115fe7b07c37fdc94 Mon Sep 17 00:00:00 2001 From: Timothy J Fontaine Date: Mon, 18 Nov 2013 15:01:38 -0800 Subject: [PATCH] v8: upgrade to 3.22.24.5 --- deps/v8/src/arm/lithium-arm.cc | 10 +- deps/v8/src/arm/lithium-arm.h | 8 ++ deps/v8/src/arm/lithium-codegen-arm.cc | 5 + deps/v8/src/arm/stub-cache-arm.cc | 72 +++++---------- deps/v8/src/hydrogen.cc | 62 +++++++++---- deps/v8/src/hydrogen.h | 13 +++ deps/v8/src/ia32/lithium-codegen-ia32.cc | 5 + deps/v8/src/ia32/lithium-ia32.cc | 10 +- deps/v8/src/ia32/lithium-ia32.h | 8 ++ deps/v8/src/ia32/stub-cache-ia32.cc | 82 ++++++----------- deps/v8/src/lithium.cc | 1 + deps/v8/src/mips/lithium-codegen-mips.cc | 20 +++- deps/v8/src/mips/lithium-mips.cc | 15 +-- deps/v8/src/mips/lithium-mips.h | 22 +++++ deps/v8/src/mips/stub-cache-mips.cc | 75 +++++---------- deps/v8/src/objects.cc | 4 +- deps/v8/src/objects.h | 8 +- deps/v8/src/runtime.cc | 4 +- deps/v8/src/stub-cache.cc | 40 +++++++- deps/v8/src/stub-cache.h | 34 ++++++- deps/v8/src/version.cc | 2 +- deps/v8/src/x64/lithium-codegen-x64.cc | 5 + deps/v8/src/x64/lithium-x64.cc | 10 +- deps/v8/src/x64/lithium-x64.h | 8 ++ deps/v8/src/x64/stub-cache-x64.cc | 91 +++++++------------ deps/v8/test/mjsunit/regress/regress-2980.js | 64 +++++++++++++ .../v8/test/mjsunit/regress/regress-298269.js | 45 +++++++++ .../v8/test/mjsunit/regress/regress-319120.js | 28 ++++++ .../mjsunit/regress/regress-crbug-318671.js | 38 ++++++++ 29 files changed, 522 insertions(+), 267 deletions(-) create mode 100644 deps/v8/test/mjsunit/regress/regress-2980.js create mode 100644 deps/v8/test/mjsunit/regress/regress-298269.js create mode 100644 deps/v8/test/mjsunit/regress/regress-319120.js create mode 100644 deps/v8/test/mjsunit/regress/regress-crbug-318671.js diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc index 86d5d2b32902..615c835beaef 100644 --- a/deps/v8/src/arm/lithium-arm.cc +++ b/deps/v8/src/arm/lithium-arm.cc @@ -863,10 +863,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { LInstruction* instr = NULL; if (current->CanReplaceWithDummyUses()) { - HValue* first_operand = current->OperandCount() == 0 - ? graph()->GetConstant1() - : current->OperandAt(0); - instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); + if (current->OperandCount() == 0) { + instr = DefineAsRegister(new(zone()) LDummy()); + } else { + instr = DefineAsRegister(new(zone()) + LDummyUse(UseAny(current->OperandAt(0)))); + } for (int i = 1; i < current->OperandCount(); ++i) { LInstruction* dummy = new(zone()) LDummyUse(UseAny(current->OperandAt(i))); diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h index ed07229e17c5..5087fb33d2b3 100644 --- a/deps/v8/src/arm/lithium-arm.h +++ b/deps/v8/src/arm/lithium-arm.h @@ -91,6 +91,7 @@ class LCodeGen; V(DoubleToI) \ V(DoubleToSmi) \ V(Drop) \ + V(Dummy) \ V(DummyUse) \ V(ElementsKind) \ V(ForInCacheArray) \ @@ -423,6 +424,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> { }; +class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> { + public: + explicit LDummy() { } + DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") +}; + + class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: explicit LDummyUse(LOperand* value) { diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index fbe8e171fa59..8b22e625ba4c 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -5650,6 +5650,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { } +void LCodeGen::DoDummy(LDummy* instr) { + // Nothing to see here, move on! +} + + void LCodeGen::DoDummyUse(LDummyUse* instr) { // Nothing to see here, move on! } diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc index 004e067c8257..923011fe0899 100644 --- a/deps/v8/src/arm/stub-cache-arm.cc +++ b/deps/v8/src/arm/stub-cache-arm.cc @@ -121,18 +121,14 @@ static void ProbeTable(Isolate* isolate, } -// Helper function used to check that the dictionary doesn't contain -// the property. This function may return false negatives, so miss_label -// must always call a backup property check that is complete. -// This function is safe to call if the receiver has fast properties. -// Name must be unique and receiver must be a heap object. -static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, - Label* miss_label, - Register receiver, - Handle name, - Register scratch0, - Register scratch1) { +void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, + Label* miss_label, + Register receiver, + Handle name, + Register scratch0, + Register scratch1) { ASSERT(name->IsUniqueName()); + ASSERT(!receiver.is(scratch0)); Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); @@ -418,12 +414,12 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, // Generate code to check that a global property cell is empty. Create // the property cell at compilation time if no cell exists for the // property. -static void GenerateCheckPropertyCell(MacroAssembler* masm, - Handle global, - Handle name, - Register scratch, - Label* miss) { - Handle cell = GlobalObject::EnsurePropertyCell(global, name); +void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, + Handle global, + Handle name, + Register scratch, + Label* miss) { + Handle cell = JSGlobalObject::EnsurePropertyCell(global, name); ASSERT(cell->value()->IsTheHole()); __ mov(scratch, Operand(cell)); __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); @@ -441,7 +437,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup( Label* miss) { if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell( - masm, Handle::cast(holder), name, scratch1(), miss); + masm, Handle::cast(holder), name, scratch1(), miss); } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup( masm, miss, holder_reg, name, scratch1(), scratch2()); @@ -1156,19 +1152,17 @@ class CallInterceptorCompiler BASE_EMBEDDED { }; -// Calls GenerateCheckPropertyCell for each global object in the prototype chain -// from object to (but not including) holder. -static void GenerateCheckPropertyCells(MacroAssembler* masm, - Handle object, - Handle holder, - Handle name, - Register scratch, - Label* miss) { +void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, + Handle object, + Handle holder, + Handle name, + Register scratch, + Label* miss) { Handle current = object; while (!current.is_identical_to(holder)) { - if (current->IsGlobalObject()) { + if (current->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm, - Handle::cast(current), + Handle::cast(current), name, scratch, miss); @@ -1373,26 +1367,6 @@ Register LoadStubCompiler::CallbackHandlerFrontend( } -void LoadStubCompiler::NonexistentHandlerFrontend( - Handle object, - Handle last, - Handle name, - Label* success, - Handle global) { - Label miss; - - HandlerFrontendHeader(object, receiver(), last, name, &miss); - - // If the last object in the prototype chain is a global object, - // check that the global property cell is empty. - if (!global.is_null()) { - GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); - } - - HandlerFrontendFooter(name, success, &miss); -} - - void LoadStubCompiler::GenerateLoadField(Register reg, Handle holder, PropertyIndex field, @@ -2939,7 +2913,7 @@ Handle LoadStubCompiler::CompileLoadNonexistent( Handle object, Handle last, Handle name, - Handle global) { + Handle global) { Label success; NonexistentHandlerFrontend(object, last, name, &success, global); diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc index 3b232e6e93ee..9587dd3440e7 100644 --- a/deps/v8/src/hydrogen.cc +++ b/deps/v8/src/hydrogen.cc @@ -708,6 +708,21 @@ DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false) #undef DEFINE_GET_CONSTANT +#define DEFINE_IS_CONSTANT(Name, name) \ +bool HGraph::IsConstant##Name(HConstant* constant) { \ + return constant_##name##_.is_set() && constant == constant_##name##_.get(); \ +} +DEFINE_IS_CONSTANT(Undefined, undefined) +DEFINE_IS_CONSTANT(0, 0) +DEFINE_IS_CONSTANT(1, 1) +DEFINE_IS_CONSTANT(Minus1, minus1) +DEFINE_IS_CONSTANT(True, true) +DEFINE_IS_CONSTANT(False, false) +DEFINE_IS_CONSTANT(Hole, the_hole) +DEFINE_IS_CONSTANT(Null, null) + +#undef DEFINE_IS_CONSTANT + HConstant* HGraph::GetInvalidContext() { return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); @@ -715,14 +730,14 @@ HConstant* HGraph::GetInvalidContext() { bool HGraph::IsStandardConstant(HConstant* constant) { - if (constant == GetConstantUndefined()) return true; - if (constant == GetConstant0()) return true; - if (constant == GetConstant1()) return true; - if (constant == GetConstantMinus1()) return true; - if (constant == GetConstantTrue()) return true; - if (constant == GetConstantFalse()) return true; - if (constant == GetConstantHole()) return true; - if (constant == GetConstantNull()) return true; + if (IsConstantUndefined(constant)) return true; + if (IsConstant0(constant)) return true; + if (IsConstant1(constant)) return true; + if (IsConstantMinus1(constant)) return true; + if (IsConstantTrue(constant)) return true; + if (IsConstantFalse(constant)) return true; + if (IsConstantHole(constant)) return true; + if (IsConstantNull(constant)) return true; return false; } @@ -2281,7 +2296,8 @@ HGraph::HGraph(CompilationInfo* info) depends_on_empty_array_proto_elements_(false), type_change_checksum_(0), maximum_environment_size_(0), - no_side_effects_scope_count_(0) { + no_side_effects_scope_count_(0), + disallow_adding_new_values_(false) { if (info->IsStub()) { HydrogenCodeStub* stub = info->code_stub(); CodeStubInterfaceDescriptor* descriptor = @@ -7830,14 +7846,27 @@ HInstruction* HGraphBuilder::BuildBinaryOperation( // Special case for string addition here. if (op == Token::ADD && (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { + // Validate type feedback for left argument. if (left_type->Is(Type::String())) { IfBuilder if_isstring(this); if_isstring.If(left); if_isstring.Then(); if_isstring.ElseDeopt("Expected string for LHS of binary operation"); - } else if (left_type->Is(Type::Number())) { + } + + // Validate type feedback for right argument. + if (right_type->Is(Type::String())) { + IfBuilder if_isstring(this); + if_isstring.If(right); + if_isstring.Then(); + if_isstring.ElseDeopt("Expected string for RHS of binary operation"); + } + + // Convert left argument as necessary. + if (left_type->Is(Type::Number())) { + ASSERT(right_type->Is(Type::String())); left = BuildNumberToString(left, left_type); - } else { + } else if (!left_type->Is(Type::String())) { ASSERT(right_type->Is(Type::String())); HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); Add(left); @@ -7845,14 +7874,11 @@ HInstruction* HGraphBuilder::BuildBinaryOperation( return NewUncasted(function, 2); } - if (right_type->Is(Type::String())) { - IfBuilder if_isstring(this); - if_isstring.If(right); - if_isstring.Then(); - if_isstring.ElseDeopt("Expected string for RHS of binary operation"); - } else if (right_type->Is(Type::Number())) { + // Convert right argument as necessary. + if (right_type->Is(Type::Number())) { + ASSERT(left_type->Is(Type::String())); right = BuildNumberToString(right, right_type); - } else { + } else if (!right_type->Is(Type::String())) { ASSERT(left_type->Is(Type::String())); HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); Add(left); diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h index b5046bd00190..8f4878d93e9c 100644 --- a/deps/v8/src/hydrogen.h +++ b/deps/v8/src/hydrogen.h @@ -352,6 +352,14 @@ class HGraph V8_FINAL : public ZoneObject { HConstant* GetConstantNull(); HConstant* GetInvalidContext(); + bool IsConstantUndefined(HConstant* constant); + bool IsConstant0(HConstant* constant); + bool IsConstant1(HConstant* constant); + bool IsConstantMinus1(HConstant* constant); + bool IsConstantTrue(HConstant* constant); + bool IsConstantFalse(HConstant* constant); + bool IsConstantHole(HConstant* constant); + bool IsConstantNull(HConstant* constant); bool IsStandardConstant(HConstant* constant); HBasicBlock* CreateBasicBlock(); @@ -366,6 +374,7 @@ class HGraph V8_FINAL : public ZoneObject { int GetMaximumValueID() const { return values_.length(); } int GetNextBlockID() { return next_block_id_++; } int GetNextValueID(HValue* value) { + ASSERT(!disallow_adding_new_values_); values_.Add(value, zone()); return values_.length() - 1; } @@ -373,6 +382,9 @@ class HGraph V8_FINAL : public ZoneObject { if (id >= 0 && id < values_.length()) return values_[id]; return NULL; } + void DisallowAddingNewValues() { + disallow_adding_new_values_ = true; + } bool Optimize(BailoutReason* bailout_reason); @@ -499,6 +511,7 @@ class HGraph V8_FINAL : public ZoneObject { int type_change_checksum_; int maximum_environment_size_; int no_side_effects_scope_count_; + bool disallow_adding_new_values_; DISALLOW_COPY_AND_ASSIGN(HGraph); }; diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc index 46c87e1d62a9..0c7e8d6ef32b 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.cc +++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc @@ -6216,6 +6216,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { } +void LCodeGen::DoDummy(LDummy* instr) { + // Nothing to see here, move on! +} + + void LCodeGen::DoDummyUse(LDummyUse* instr) { // Nothing to see here, move on! } diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc index fdddef3f479a..73aabd6b1e05 100644 --- a/deps/v8/src/ia32/lithium-ia32.cc +++ b/deps/v8/src/ia32/lithium-ia32.cc @@ -916,10 +916,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { LInstruction* instr = NULL; if (current->CanReplaceWithDummyUses()) { - HValue* first_operand = current->OperandCount() == 0 - ? graph()->GetConstant1() - : current->OperandAt(0); - instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); + if (current->OperandCount() == 0) { + instr = DefineAsRegister(new(zone()) LDummy()); + } else { + instr = DefineAsRegister(new(zone()) + LDummyUse(UseAny(current->OperandAt(0)))); + } for (int i = 1; i < current->OperandCount(); ++i) { LInstruction* dummy = new(zone()) LDummyUse(UseAny(current->OperandAt(i))); diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h index 752fdd4f6afb..9b00f3c35887 100644 --- a/deps/v8/src/ia32/lithium-ia32.h +++ b/deps/v8/src/ia32/lithium-ia32.h @@ -93,6 +93,7 @@ class LCodeGen; V(DoubleToI) \ V(DoubleToSmi) \ V(Drop) \ + V(Dummy) \ V(DummyUse) \ V(ElementsKind) \ V(ForInCacheArray) \ @@ -431,6 +432,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> { }; +class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> { + public: + explicit LDummy() { } + DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") +}; + + class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: explicit LDummyUse(LOperand* value) { diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc index 9786cffe8660..0648833dc756 100644 --- a/deps/v8/src/ia32/stub-cache-ia32.cc +++ b/deps/v8/src/ia32/stub-cache-ia32.cc @@ -137,38 +137,34 @@ static void ProbeTable(Isolate* isolate, } -// Helper function used to check that the dictionary doesn't contain -// the property. This function may return false negatives, so miss_label -// must always call a backup property check that is complete. -// This function is safe to call if the receiver has fast properties. -// Name must be unique and receiver must be a heap object. -static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, - Label* miss_label, - Register receiver, - Handle name, - Register r0, - Register r1) { +void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, + Label* miss_label, + Register receiver, + Handle name, + Register scratch0, + Register scratch1) { ASSERT(name->IsUniqueName()); + ASSERT(!receiver.is(scratch0)); Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->negative_lookups(), 1); __ IncrementCounter(counters->negative_lookups_miss(), 1); - __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); + __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); const int kInterceptorOrAccessCheckNeededMask = (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); // Bail out if the receiver has a named interceptor or requires access checks. - __ test_b(FieldOperand(r0, Map::kBitFieldOffset), + __ test_b(FieldOperand(scratch0, Map::kBitFieldOffset), kInterceptorOrAccessCheckNeededMask); __ j(not_zero, miss_label); // Check that receiver is a JSObject. - __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); + __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE); __ j(below, miss_label); // Load properties array. - Register properties = r0; + Register properties = scratch0; __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); // Check that the properties array is a dictionary. @@ -182,7 +178,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, &done, properties, name, - r1); + scratch1); __ bind(&done); __ DecrementCounter(counters->negative_lookups_miss(), 1); } @@ -792,13 +788,13 @@ void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, // Generate code to check that a global property cell is empty. Create // the property cell at compilation time if no cell exists for the // property. -static void GenerateCheckPropertyCell(MacroAssembler* masm, - Handle global, - Handle name, - Register scratch, - Label* miss) { +void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, + Handle global, + Handle name, + Register scratch, + Label* miss) { Handle cell = - GlobalObject::EnsurePropertyCell(global, name); + JSGlobalObject::EnsurePropertyCell(global, name); ASSERT(cell->value()->IsTheHole()); Handle the_hole = masm->isolate()->factory()->the_hole_value(); if (Serializer::enabled()) { @@ -820,7 +816,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup( Label* miss) { if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell( - masm, Handle::cast(holder), name, scratch1(), miss); + masm, Handle::cast(holder), name, scratch1(), miss); } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup( masm, miss, holder_reg, name, scratch1(), scratch2()); @@ -1122,19 +1118,17 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, } -// Calls GenerateCheckPropertyCell for each global object in the prototype chain -// from object to (but not including) holder. -static void GenerateCheckPropertyCells(MacroAssembler* masm, - Handle object, - Handle holder, - Handle name, - Register scratch, - Label* miss) { +void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, + Handle object, + Handle holder, + Handle name, + Register scratch, + Label* miss) { Handle current = object; while (!current.is_identical_to(holder)) { - if (current->IsGlobalObject()) { + if (current->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm, - Handle::cast(current), + Handle::cast(current), name, scratch, miss); @@ -1355,26 +1349,6 @@ Register LoadStubCompiler::CallbackHandlerFrontend( } -void LoadStubCompiler::NonexistentHandlerFrontend( - Handle object, - Handle last, - Handle name, - Label* success, - Handle global) { - Label miss; - - HandlerFrontendHeader(object, receiver(), last, name, &miss); - - // If the last object in the prototype chain is a global object, - // check that the global property cell is empty. - if (!global.is_null()) { - GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); - } - - HandlerFrontendFooter(name, success, &miss); -} - - void LoadStubCompiler::GenerateLoadField(Register reg, Handle holder, PropertyIndex field, @@ -3049,7 +3023,7 @@ Handle LoadStubCompiler::CompileLoadNonexistent( Handle object, Handle last, Handle name, - Handle global) { + Handle global) { Label success; NonexistentHandlerFrontend(object, last, name, &success, global); diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc index 1be4b0654bbb..966afa9c0b88 100644 --- a/deps/v8/src/lithium.cc +++ b/deps/v8/src/lithium.cc @@ -422,6 +422,7 @@ Representation LChunk::LookupLiteralRepresentation( LChunk* LChunk::NewChunk(HGraph* graph) { DisallowHandleAllocation no_handles; DisallowHeapAllocation no_gc; + graph->DisallowAddingNewValues(); int values = graph->GetMaximumValueID(); CompilationInfo* info = graph->info(); if (values > LUnallocated::kMaxVirtualRegisters) { diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc index f54d4a5b0cd9..4484dc634ed1 100644 --- a/deps/v8/src/mips/lithium-codegen-mips.cc +++ b/deps/v8/src/mips/lithium-codegen-mips.cc @@ -4584,9 +4584,7 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { LOperand* input = instr->value(); - ASSERT(input->IsRegister()); LOperand* output = instr->result(); - ASSERT(output->IsRegister()); Register scratch = scratch0(); __ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch); @@ -4607,6 +4605,19 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { } +void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) { + LOperand* input = instr->value(); + LOperand* output = instr->result(); + if (!instr->hydrogen()->value()->HasRange() || + !instr->hydrogen()->value()->range()->IsInSmiRange()) { + Register scratch = scratch0(); + __ And(scratch, ToRegister(input), Operand(0xc0000000)); + DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); + } + __ SmiTag(ToRegister(output), ToRegister(input)); +} + + void LCodeGen::DoNumberTagI(LNumberTagI* instr) { class DeferredNumberTagI V8_FINAL : public LDeferredCode { public: @@ -5631,6 +5642,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { } +void LCodeGen::DoDummy(LDummy* instr) { + // Nothing to see here, move on! +} + + void LCodeGen::DoDummyUse(LDummyUse* instr) { // Nothing to see here, move on! } diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc index fb94bc3bdf24..6b76ff742902 100644 --- a/deps/v8/src/mips/lithium-mips.cc +++ b/deps/v8/src/mips/lithium-mips.cc @@ -868,10 +868,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { LInstruction* instr = NULL; if (current->CanReplaceWithDummyUses()) { - HValue* first_operand = current->OperandCount() == 0 - ? graph()->GetConstant1() - : current->OperandAt(0); - instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); + if (current->OperandCount() == 0) { + instr = DefineAsRegister(new(zone()) LDummy()); + } else { + instr = DefineAsRegister(new(zone()) + LDummyUse(UseAny(current->OperandAt(0)))); + } for (int i = 1; i < current->OperandCount(); ++i) { LInstruction* dummy = new(zone()) LDummyUse(UseAny(current->OperandAt(i))); @@ -1934,8 +1936,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { } else if (to.IsSmi()) { HValue* val = instr->value(); LOperand* value = UseRegister(val); - LInstruction* result = - DefineSameAsFirst(new(zone()) LInteger32ToSmi(value)); + LInstruction* result = val->CheckFlag(HInstruction::kUint32) + ? DefineSameAsFirst(new(zone()) LUint32ToSmi(value)) + : DefineSameAsFirst(new(zone()) LInteger32ToSmi(value)); if (val->HasRange() && val->range()->IsInSmiRange()) { return result; } diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h index 301be8fdf2c7..518a3b8c6599 100644 --- a/deps/v8/src/mips/lithium-mips.h +++ b/deps/v8/src/mips/lithium-mips.h @@ -91,6 +91,7 @@ class LCodeGen; V(DoubleToI) \ V(DoubleToSmi) \ V(Drop) \ + V(Dummy) \ V(DummyUse) \ V(ElementsKind) \ V(ForInCacheArray) \ @@ -182,6 +183,7 @@ class LCodeGen; V(Typeof) \ V(TypeofIsAndBranch) \ V(Uint32ToDouble) \ + V(Uint32ToSmi) \ V(UnknownOSRValue) \ V(ValueOf) \ V(WrapReceiver) @@ -419,6 +421,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> { }; +class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> { + public: + explicit LDummy() { } + DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") +}; + + class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: explicit LDummyUse(LOperand* value) { @@ -2052,6 +2061,19 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> { }; +class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> { + public: + explicit LUint32ToSmi(LOperand* value) { + inputs_[0] = value; + } + + LOperand* value() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi") + DECLARE_HYDROGEN_ACCESSOR(Change) +}; + + class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: explicit LNumberTagI(LOperand* value) { diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc index 471c25ef824d..17aa4aadef03 100644 --- a/deps/v8/src/mips/stub-cache-mips.cc +++ b/deps/v8/src/mips/stub-cache-mips.cc @@ -117,18 +117,14 @@ static void ProbeTable(Isolate* isolate, } -// Helper function used to check that the dictionary doesn't contain -// the property. This function may return false negatives, so miss_label -// must always call a backup property check that is complete. -// This function is safe to call if the receiver has fast properties. -// Name must be unique and receiver must be a heap object. -static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, - Label* miss_label, - Register receiver, - Handle name, - Register scratch0, - Register scratch1) { +void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, + Label* miss_label, + Register receiver, + Handle name, + Register scratch0, + Register scratch1) { ASSERT(name->IsUniqueName()); + ASSERT(!receiver.is(scratch0)); Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); @@ -408,15 +404,12 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, } -// Generate code to check that a global property cell is empty. Create -// the property cell at compilation time if no cell exists for the -// property. -static void GenerateCheckPropertyCell(MacroAssembler* masm, - Handle global, - Handle name, - Register scratch, - Label* miss) { - Handle cell = GlobalObject::EnsurePropertyCell(global, name); +void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, + Handle global, + Handle name, + Register scratch, + Label* miss) { + Handle cell = JSGlobalObject::EnsurePropertyCell(global, name); ASSERT(cell->value()->IsTheHole()); __ li(scratch, Operand(cell)); __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); @@ -433,7 +426,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup( Label* miss) { if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell( - masm, Handle::cast(holder), name, scratch1(), miss); + masm, Handle::cast(holder), name, scratch1(), miss); } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup( masm, miss, holder_reg, name, scratch1(), scratch2()); @@ -1149,19 +1142,17 @@ class CallInterceptorCompiler BASE_EMBEDDED { }; -// Calls GenerateCheckPropertyCell for each global object in the prototype chain -// from object to (but not including) holder. -static void GenerateCheckPropertyCells(MacroAssembler* masm, - Handle object, - Handle holder, - Handle name, - Register scratch, - Label* miss) { +void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, + Handle object, + Handle holder, + Handle name, + Register scratch, + Label* miss) { Handle current = object; while (!current.is_identical_to(holder)) { - if (current->IsGlobalObject()) { + if (current->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm, - Handle::cast(current), + Handle::cast(current), name, scratch, miss); @@ -1364,26 +1355,6 @@ Register LoadStubCompiler::CallbackHandlerFrontend( } -void LoadStubCompiler::NonexistentHandlerFrontend( - Handle object, - Handle last, - Handle name, - Label* success, - Handle global) { - Label miss; - - HandlerFrontendHeader(object, receiver(), last, name, &miss); - - // If the last object in the prototype chain is a global object, - // check that the global property cell is empty. - if (!global.is_null()) { - GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); - } - - HandlerFrontendFooter(name, success, &miss); -} - - void LoadStubCompiler::GenerateLoadField(Register reg, Handle holder, PropertyIndex field, @@ -2957,7 +2928,7 @@ Handle LoadStubCompiler::CompileLoadNonexistent( Handle object, Handle last, Handle name, - Handle global) { + Handle global) { Label success; NonexistentHandlerFrontend(object, last, name, &success, global); diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index f7c89175da75..22c01bf1a36f 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -14749,8 +14749,8 @@ PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { } -Handle GlobalObject::EnsurePropertyCell( - Handle global, +Handle JSGlobalObject::EnsurePropertyCell( + Handle global, Handle name) { ASSERT(!global->HasFastProperties()); int entry = global->property_dictionary()->FindEntry(*name); diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index e8c985048455..8331a7688565 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -7389,10 +7389,6 @@ class GlobalObject: public JSObject { return answer; } - // Ensure that the global object has a cell for the given property name. - static Handle EnsurePropertyCell(Handle global, - Handle name); - // Casting. static inline GlobalObject* cast(Object* obj); @@ -7414,6 +7410,10 @@ class JSGlobalObject: public GlobalObject { // Casting. static inline JSGlobalObject* cast(Object* obj); + // Ensure that the global object has a cell for the given property name. + static Handle EnsurePropertyCell(Handle global, + Handle name); + // Dispatched behavior. DECLARE_PRINTER(JSGlobalObject) DECLARE_VERIFIER(JSGlobalObject) diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc index 15cfc854bfad..7f37af0bd724 100644 --- a/deps/v8/src/runtime.cc +++ b/deps/v8/src/runtime.cc @@ -961,12 +961,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) { Handle buffer = isolate->factory()->NewJSArrayBuffer(); size_t length = NumberToSize(isolate, *length_obj); - size_t byte_length = length * element_size; - if (byte_length < length) { // Overflow + if (length > (kMaxInt / element_size)) { return isolate->Throw(*isolate->factory()-> NewRangeError("invalid_array_buffer_length", HandleVector(NULL, 0))); } + size_t byte_length = length * element_size; // NOTE: not initializing backing store. // We assume that the caller of this function will initialize holder diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc index 67002a36b17a..1ec00d49bb30 100644 --- a/deps/v8/src/stub-cache.cc +++ b/deps/v8/src/stub-cache.cc @@ -177,12 +177,12 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, Handle cache_name = factory()->empty_string(); Handle current; Handle next = receiver; - Handle global; + Handle global; do { current = Handle::cast(next); next = Handle(current->GetPrototype(), isolate_); - if (current->IsGlobalObject()) { - global = Handle::cast(current); + if (current->IsJSGlobalObject()) { + global = Handle::cast(current); cache_name = name; } else if (!current->HasFastProperties()) { cache_name = name; @@ -1208,6 +1208,40 @@ Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle object, } +void LoadStubCompiler::NonexistentHandlerFrontend( + Handle object, + Handle last, + Handle name, + Label* success, + Handle global) { + Label miss; + + Register holder = + HandlerFrontendHeader(object, receiver(), last, name, &miss); + + if (!last->HasFastProperties() && + !last->IsJSGlobalObject() && + !last->IsJSGlobalProxy()) { + if (!name->IsUniqueName()) { + ASSERT(name->IsString()); + name = factory()->InternalizeString(Handle::cast(name)); + } + ASSERT(last->property_dictionary()->FindEntry(*name) == + NameDictionary::kNotFound); + GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, + scratch2(), scratch3()); + } + + // If the last object in the prototype chain is a global object, + // check that the global property cell is empty. + if (!global.is_null()) { + GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); + } + + HandlerFrontendFooter(name, success, &miss); +} + + Handle LoadStubCompiler::CompileLoadField( Handle object, Handle holder, diff --git a/deps/v8/src/stub-cache.h b/deps/v8/src/stub-cache.h index 38bc7a3c3a6f..42685b2059d4 100644 --- a/deps/v8/src/stub-cache.h +++ b/deps/v8/src/stub-cache.h @@ -434,6 +434,18 @@ class StubCompiler BASE_EMBEDDED { int index, Register prototype); + // Helper function used to check that the dictionary doesn't contain + // the property. This function may return false negatives, so miss_label + // must always call a backup property check that is complete. + // This function is safe to call if the receiver has fast properties. + // Name must be unique and receiver must be a heap object. + static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, + Label* miss_label, + Register receiver, + Handle name, + Register r0, + Register r1); + // Generates prototype loading code that uses the objects from the // context we were in when this function was called. If the context // has changed, a jump to miss is performed. This ties the generated @@ -469,6 +481,24 @@ class StubCompiler BASE_EMBEDDED { Register scratch2, Label* miss_label); + // Generate code to check that a global property cell is empty. Create + // the property cell at compilation time if no cell exists for the + // property. + static void GenerateCheckPropertyCell(MacroAssembler* masm, + Handle global, + Handle name, + Register scratch, + Label* miss); + + // Calls GenerateCheckPropertyCell for each global object in the prototype + // chain from object to (but not including) holder. + static void GenerateCheckPropertyCells(MacroAssembler* masm, + Handle object, + Handle holder, + Handle name, + Register scratch, + Label* miss); + static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name); // Generates code that verifies that the property holder has not changed @@ -673,7 +703,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { Handle CompileLoadNonexistent(Handle object, Handle last, Handle name, - Handle global); + Handle global); Handle CompileLoadGlobal(Handle object, Handle holder, @@ -704,7 +734,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { Handle last, Handle name, Label* success, - Handle global); + Handle global); void GenerateLoadField(Register reg, Handle holder, diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc index 6d4efa22619b..dcf8df7e2a11 100644 --- a/deps/v8/src/version.cc +++ b/deps/v8/src/version.cc @@ -35,7 +35,7 @@ #define MAJOR_VERSION 3 #define MINOR_VERSION 22 #define BUILD_NUMBER 24 -#define PATCH_LEVEL 0 +#define PATCH_LEVEL 5 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) #define IS_CANDIDATE_VERSION 0 diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc index 7c70094fbf03..31fbcd27abb5 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.cc +++ b/deps/v8/src/x64/lithium-codegen-x64.cc @@ -5304,6 +5304,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { } +void LCodeGen::DoDummy(LDummy* instr) { + // Nothing to see here, move on! +} + + void LCodeGen::DoDummyUse(LDummyUse* instr) { // Nothing to see here, move on! } diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc index 6262e7ede377..8f26a09e969f 100644 --- a/deps/v8/src/x64/lithium-x64.cc +++ b/deps/v8/src/x64/lithium-x64.cc @@ -862,10 +862,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { LInstruction* instr = NULL; if (current->CanReplaceWithDummyUses()) { - HValue* first_operand = current->OperandCount() == 0 - ? graph()->GetConstant1() - : current->OperandAt(0); - instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); + if (current->OperandCount() == 0) { + instr = DefineAsRegister(new(zone()) LDummy()); + } else { + instr = DefineAsRegister(new(zone()) + LDummyUse(UseAny(current->OperandAt(0)))); + } for (int i = 1; i < current->OperandCount(); ++i) { LInstruction* dummy = new(zone()) LDummyUse(UseAny(current->OperandAt(i))); diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h index 06cb1719233a..1a889b3964b5 100644 --- a/deps/v8/src/x64/lithium-x64.h +++ b/deps/v8/src/x64/lithium-x64.h @@ -92,6 +92,7 @@ class LCodeGen; V(DoubleToSmi) \ V(Drop) \ V(DummyUse) \ + V(Dummy) \ V(ElementsKind) \ V(ForInCacheArray) \ V(ForInPrepareMap) \ @@ -422,6 +423,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> { }; +class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> { + public: + explicit LDummy() { } + DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") +}; + + class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: explicit LDummyUse(LOperand* value) { diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc index 2a0c3675f204..28e2a89627f4 100644 --- a/deps/v8/src/x64/stub-cache-x64.cc +++ b/deps/v8/src/x64/stub-cache-x64.cc @@ -107,38 +107,34 @@ static void ProbeTable(Isolate* isolate, } -// Helper function used to check that the dictionary doesn't contain -// the property. This function may return false negatives, so miss_label -// must always call a backup property check that is complete. -// This function is safe to call if the receiver has fast properties. -// Name must be unique and receiver must be a heap object. -static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, - Label* miss_label, - Register receiver, - Handle name, - Register r0, - Register r1) { +void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, + Label* miss_label, + Register receiver, + Handle name, + Register scratch0, + Register scratch1) { ASSERT(name->IsUniqueName()); + ASSERT(!receiver.is(scratch0)); Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->negative_lookups(), 1); __ IncrementCounter(counters->negative_lookups_miss(), 1); - __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); + __ movq(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); const int kInterceptorOrAccessCheckNeededMask = (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); // Bail out if the receiver has a named interceptor or requires access checks. - __ testb(FieldOperand(r0, Map::kBitFieldOffset), + __ testb(FieldOperand(scratch0, Map::kBitFieldOffset), Immediate(kInterceptorOrAccessCheckNeededMask)); __ j(not_zero, miss_label); // Check that receiver is a JSObject. - __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); + __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE); __ j(below, miss_label); // Load properties array. - Register properties = r0; + Register properties = scratch0; __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); // Check that the properties array is a dictionary. @@ -152,7 +148,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, &done, properties, name, - r1); + scratch1); __ bind(&done); __ DecrementCounter(counters->negative_lookups_miss(), 1); } @@ -777,16 +773,13 @@ void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, } -// Generate code to check that a global property cell is empty. Create -// the property cell at compilation time if no cell exists for the -// property. -static void GenerateCheckPropertyCell(MacroAssembler* masm, - Handle global, - Handle name, - Register scratch, - Label* miss) { +void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, + Handle global, + Handle name, + Register scratch, + Label* miss) { Handle cell = - GlobalObject::EnsurePropertyCell(global, name); + JSGlobalObject::EnsurePropertyCell(global, name); ASSERT(cell->value()->IsTheHole()); __ Move(scratch, cell); __ Cmp(FieldOperand(scratch, Cell::kValueOffset), @@ -803,7 +796,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup( Label* miss) { if (holder->IsJSGlobalObject()) { GenerateCheckPropertyCell( - masm, Handle::cast(holder), name, scratch1(), miss); + masm, Handle::cast(holder), name, scratch1(), miss); } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { GenerateDictionaryNegativeLookup( masm, miss, holder_reg, name, scratch1(), scratch2()); @@ -1054,19 +1047,17 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, } -// Calls GenerateCheckPropertyCell for each global object in the prototype chain -// from object to (but not including) holder. -static void GenerateCheckPropertyCells(MacroAssembler* masm, - Handle object, - Handle holder, - Handle name, - Register scratch, - Label* miss) { +void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, + Handle object, + Handle holder, + Handle name, + Register scratch, + Label* miss) { Handle current = object; while (!current.is_identical_to(holder)) { - if (current->IsGlobalObject()) { + if (current->IsJSGlobalObject()) { GenerateCheckPropertyCell(masm, - Handle::cast(current), + Handle::cast(current), name, scratch, miss); @@ -1282,30 +1273,10 @@ Register LoadStubCompiler::CallbackHandlerFrontend( } -void LoadStubCompiler::NonexistentHandlerFrontend( - Handle object, - Handle last, - Handle name, - Label* success, - Handle global) { - Label miss; - - HandlerFrontendHeader(object, receiver(), last, name, &miss); - - // If the last object in the prototype chain is a global object, - // check that the global property cell is empty. - if (!global.is_null()) { - GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); - } - - HandlerFrontendFooter(name, success, &miss); -} - - void LoadStubCompiler::GenerateLoadField(Register reg, - Handle holder, - PropertyIndex field, - Representation representation) { + Handle holder, + PropertyIndex field, + Representation representation) { if (!reg.is(receiver())) __ movq(receiver(), reg); if (kind() == Code::LOAD_IC) { LoadFieldStub stub(field.is_inobject(holder), @@ -2957,7 +2928,7 @@ Handle LoadStubCompiler::CompileLoadNonexistent( Handle object, Handle last, Handle name, - Handle global) { + Handle global) { Label success; NonexistentHandlerFrontend(object, last, name, &success, global); diff --git a/deps/v8/test/mjsunit/regress/regress-2980.js b/deps/v8/test/mjsunit/regress/regress-2980.js new file mode 100644 index 000000000000..071a73353a79 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-2980.js @@ -0,0 +1,64 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +function test(expected, holder) { + assertEquals(expected, holder.property); +} + +var holder = {} +holder.__proto__ = null; +holder.property = "foo"; +delete holder.property; +test(undefined, holder); +test(undefined, holder); +test(undefined, holder); +holder.property = "bar"; +test("bar", holder); +test("bar", holder); + +// Now the same thing with a nontrivial prototype chain. + +function test2(expected, holder) { + assertEquals(expected, holder.prop2); +} + +var holder2 = {} +holder2.prop2 = "foo"; +holder2.__proto__ = null; +function Receiver() {} +Receiver.prototype = holder2; + +var rec2 = new Receiver(); +delete holder2.prop2; + +test2(undefined, rec2); +test2(undefined, rec2); +test2(undefined, rec2); +holder2.prop2 = "bar"; +test2("bar", rec2); +test2("bar", rec2); diff --git a/deps/v8/test/mjsunit/regress/regress-298269.js b/deps/v8/test/mjsunit/regress/regress-298269.js new file mode 100644 index 000000000000..329ff824dff4 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-298269.js @@ -0,0 +1,45 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function Cb(a) { + var f, g; + for(f = a.length; f--;) { + g = a.charCodeAt(f); + // This will fail after OSR if Runtime_StringCharCodeAt is modified + // to iterates optimized frames and visit safepoint pointers. + } + return g; +} + +var s1 = "long string to make cons string 1"; +var s2 = "long string to make cons string 2"; +Cb(s1 + s2); +Cb(s1); +var s3 = "string for triggering osr in Cb"; +for (var i = 0; i < 16; i++) s3 = s3 + s3; +Cb(s3); +Cb(s1 + s2); \ No newline at end of file diff --git a/deps/v8/test/mjsunit/regress/regress-319120.js b/deps/v8/test/mjsunit/regress/regress-319120.js new file mode 100644 index 000000000000..2899da25d9d9 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-319120.js @@ -0,0 +1,28 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +assertThrows('x = new Float64Array({length: 0x24924925})'); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-318671.js b/deps/v8/test/mjsunit/regress/regress-crbug-318671.js new file mode 100644 index 000000000000..54a7d5eeb6c5 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-318671.js @@ -0,0 +1,38 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function add(x, y) { return x + y; } + +print(add({ a: 1 }, "a")); +print(add({ b: 1 }, "b")); +print(add({ c: 1 }, "c")); + +%OptimizeFunctionOnNextCall(add); + +print(add("a", 1));