diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2015-01-07 18:38:38 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2015-01-07 22:11:18 +0100 |
commit | dad73f645cde6920e79db956e7ef82ed640d7615 (patch) | |
tree | 7ba3f3fc7e0722c5f130065461b7c56f571af383 /deps/v8/src/ic/x87 | |
parent | 53ba494537259b18b346dc6150d6a100c557e08f (diff) | |
download | node-new-dad73f645cde6920e79db956e7ef82ed640d7615.tar.gz |
deps: upgrade v8 to 3.31.74.1
PR-URL: https://github.com/iojs/io.js/pull/243
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Diffstat (limited to 'deps/v8/src/ic/x87')
-rw-r--r-- | deps/v8/src/ic/x87/handler-compiler-x87.cc | 133 | ||||
-rw-r--r-- | deps/v8/src/ic/x87/ic-compiler-x87.cc | 19 | ||||
-rw-r--r-- | deps/v8/src/ic/x87/ic-x87.cc | 55 | ||||
-rw-r--r-- | deps/v8/src/ic/x87/stub-cache-x87.cc | 40 |
4 files changed, 171 insertions, 76 deletions
diff --git a/deps/v8/src/ic/x87/handler-compiler-x87.cc b/deps/v8/src/ic/x87/handler-compiler-x87.cc index ae637d11b7..2ff35954c8 100644 --- a/deps/v8/src/ic/x87/handler-compiler-x87.cc +++ b/deps/v8/src/ic/x87/handler-compiler-x87.cc @@ -47,6 +47,28 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( } +void PropertyHandlerCompiler::PushVectorAndSlot(Register vector, + Register slot) { + MacroAssembler* masm = this->masm(); + __ push(vector); + __ push(slot); +} + + +void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { + MacroAssembler* masm = this->masm(); + __ pop(slot); + __ pop(vector); +} + + +void PropertyHandlerCompiler::DiscardVectorAndSlot() { + MacroAssembler* masm = this->masm(); + // Remove vector and slot. + __ add(esp, Immediate(2 * kPointerSize)); +} + + void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( MacroAssembler* masm, Label* miss_label, Register receiver, Handle<Name> name, Register scratch0, Register scratch1) { @@ -88,28 +110,23 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( - MacroAssembler* masm, int index, Register prototype, Label* miss) { - // Get the global function with the given index. - Handle<JSFunction> function( - JSFunction::cast(masm->isolate()->native_context()->get(index))); - // Check we're still in the same context. - Register scratch = prototype; + MacroAssembler* masm, int index, Register result, Label* miss) { const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); - __ mov(scratch, Operand(esi, offset)); - __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); - __ cmp(Operand(scratch, Context::SlotOffset(index)), function); - __ j(not_equal, miss); - + __ mov(result, Operand(esi, offset)); + __ mov(result, FieldOperand(result, GlobalObject::kNativeContextOffset)); + __ mov(result, Operand(result, Context::SlotOffset(index))); // Load its initial map. The global functions all have initial maps. - __ Move(prototype, Immediate(Handle<Map>(function->initial_map()))); + __ mov(result, + FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); // Load the prototype from the initial map. - __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); + __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); } void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( MacroAssembler* masm, Register receiver, Register scratch1, Register scratch2, Label* miss_label) { + DCHECK(!FLAG_vector_ics); __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); __ mov(eax, scratch1); __ ret(0); @@ -329,17 +346,38 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, } -void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap( - Handle<Name> name, Handle<Map> transition) { +void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { __ mov(this->name(), Immediate(name)); - __ mov(StoreTransitionDescriptor::MapRegister(), Immediate(transition)); } -void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant, +void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition, + Register scratch, + Label* miss) { + Handle<WeakCell> cell = Map::WeakCellForMap(transition); + Register map_reg = StoreTransitionDescriptor::MapRegister(); + DCHECK(!map_reg.is(scratch)); + __ LoadWeakValue(map_reg, cell, miss); + if (transition->CanBeDeprecated()) { + __ mov(scratch, FieldOperand(map_reg, Map::kBitField3Offset)); + __ and_(scratch, Immediate(Map::Deprecated::kMask)); + __ j(not_zero, miss); + } +} + + +void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg, + int descriptor, Register value_reg, + Register scratch, Label* miss_label) { - __ CmpObject(value_reg, handle(constant, isolate())); + DCHECK(!map_reg.is(scratch)); + DCHECK(!map_reg.is(value_reg)); + DCHECK(!value_reg.is(scratch)); + __ LoadInstanceDescriptors(map_reg, scratch); + __ mov(scratch, + FieldOperand(scratch, DescriptorArray::GetValueOffset(descriptor))); + __ cmp(value_reg, scratch); __ j(not_equal, miss_label); } @@ -415,14 +453,12 @@ Register PropertyHandlerCompiler::CheckPrototypes( reg = holder_reg; // From now on the object will be in holder_reg. __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); } else { - bool in_new_space = heap()->InNewSpace(*prototype); - // Two possible reasons for loading the prototype from the map: - // (1) Can't store references to new space in code. - // (2) Handler is shared for all receivers with the same prototype - // map (but not necessarily the same prototype instance). - bool load_prototype_from_map = in_new_space || depth == 1; + Register map_reg = scratch1; + __ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset)); if (depth != 1 || check == CHECK_ALL_MAPS) { - __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); + Handle<WeakCell> cell = Map::WeakCellForMap(current_map); + __ CmpWeakValue(map_reg, cell, scratch2); + __ j(not_equal, miss); } // Check access rights to the global object. This has to happen after @@ -432,24 +468,15 @@ Register PropertyHandlerCompiler::CheckPrototypes( // global proxy (as opposed to using slow ICs). See corresponding code // in LookupForRead(). if (current_map->IsJSGlobalProxyMap()) { - __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); + __ CheckAccessGlobalProxy(reg, map_reg, scratch2, miss); + // Restore map_reg. + __ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset)); } else if (current_map->IsJSGlobalObjectMap()) { GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), name, scratch2, miss); } - - if (load_prototype_from_map) { - // Save the map in scratch1 for later. - __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); - } - reg = holder_reg; // From now on the object will be in holder_reg. - - if (load_prototype_from_map) { - __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); - } else { - __ mov(reg, prototype); - } + __ mov(reg, FieldOperand(map_reg, Map::kPrototypeOffset)); } // Go to the next object in the prototype chain. @@ -462,7 +489,10 @@ Register PropertyHandlerCompiler::CheckPrototypes( if (depth != 0 || check == CHECK_ALL_MAPS) { // Check the holder map. - __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); + __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); + Handle<WeakCell> cell = Map::WeakCellForMap(current_map); + __ CmpWeakValue(scratch1, cell, scratch2); + __ j(not_equal, miss); } // Perform security check for access to the global object. @@ -482,6 +512,10 @@ void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { Label success; __ jmp(&success); __ bind(miss); + if (IC::ICUseVector(kind())) { + DCHECK(kind() == Code::LOAD_IC); + PopVectorAndSlot(); + } TailCallBuiltin(masm(), MissBuiltin(kind())); __ bind(&success); } @@ -581,7 +615,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( } __ push(holder_reg); __ push(this->name()); - + InterceptorVectorSlotPush(holder_reg); // Invoke an interceptor. Note: map checks from receiver to // interceptor's holder has been compiled before (see a caller // of this method.) @@ -605,6 +639,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue))); } + InterceptorVectorSlotPop(holder_reg); __ pop(this->name()); __ pop(holder_reg); if (must_preserve_receiver_reg) { @@ -637,7 +672,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( Handle<JSObject> object, Handle<Name> name, Handle<ExecutableAccessorInfo> callback) { - Register holder_reg = Frontend(receiver(), name); + Register holder_reg = Frontend(name); __ pop(scratch1()); // remove the return address __ push(receiver()); @@ -683,16 +718,15 @@ Register NamedStoreHandlerCompiler::value() { Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { Label miss; - + if (IC::ICUseVector(kind())) { + PushVectorAndSlot(); + } FrontendHeader(receiver(), name, &miss); // Get the value from the cell. Register result = StoreDescriptor::ValueRegister(); - if (masm()->serializer_enabled()) { - __ mov(result, Immediate(cell)); - __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); - } else { - __ mov(result, Operand::ForCell(cell)); - } + Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); + __ LoadWeakValue(result, weak_cell, &miss); + __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); // Check for deleted property if property can actually be deleted. if (is_configurable) { @@ -706,6 +740,9 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( Counters* counters = isolate()->counters(); __ IncrementCounter(counters->named_load_global_stub(), 1); // The code above already loads the result into the return register. + if (IC::ICUseVector(kind())) { + DiscardVectorAndSlot(); + } __ ret(0); FrontendFooter(name, &miss); diff --git a/deps/v8/src/ic/x87/ic-compiler-x87.cc b/deps/v8/src/ic/x87/ic-compiler-x87.cc index 20b47e726e..89bd937480 100644 --- a/deps/v8/src/ic/x87/ic-compiler-x87.cc +++ b/deps/v8/src/ic/x87/ic-compiler-x87.cc @@ -44,10 +44,13 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, Label miss; if (check == PROPERTY && - (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { - // In case we are compiling an IC for dictionary loads and stores, just + (kind() == Code::KEYED_STORE_IC || kind() == Code::KEYED_LOAD_IC)) { + // In case we are compiling an IC for dictionary loads or stores, just // check whether the name is unique. if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) { + // Keyed loads with dictionaries shouldn't be here, they go generic. + // The DCHECK is to protect assumptions when --vector-ics is on. + DCHECK(kind() != Code::KEYED_LOAD_IC); Register tmp = scratch1(); __ JumpIfSmi(this->name(), &miss); __ mov(tmp, FieldOperand(this->name(), HeapObject::kMapOffset)); @@ -75,7 +78,8 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, Handle<Map> map = IC::TypeToMap(*type, isolate()); if (!map->is_deprecated()) { number_of_handled_maps++; - __ cmp(map_reg, map); + Handle<WeakCell> cell = Map::WeakCellForMap(map); + __ CmpWeakValue(map_reg, cell, scratch2()); if (type->Is(HeapType::Number())) { DCHECK(!number_case.is_unused()); __ bind(&number_case); @@ -100,15 +104,18 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( MapHandleList* transitioned_maps) { Label miss; __ JumpIfSmi(receiver(), &miss, Label::kNear); - __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); + Register map_reg = scratch1(); + __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); for (int i = 0; i < receiver_maps->length(); ++i) { - __ cmp(scratch1(), receiver_maps->at(i)); + Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i)); + __ CmpWeakValue(map_reg, cell, scratch2()); if (transitioned_maps->at(i).is_null()) { __ j(equal, handler_stubs->at(i)); } else { Label next_map; __ j(not_equal, &next_map, Label::kNear); - __ mov(transition_map(), Immediate(transitioned_maps->at(i))); + Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i)); + __ LoadWeakValue(transition_map(), cell, &miss); __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); __ bind(&next_map); } diff --git a/deps/v8/src/ic/x87/ic-x87.cc b/deps/v8/src/ic/x87/ic-x87.cc index 959b8b628e..1004ac036b 100644 --- a/deps/v8/src/ic/x87/ic-x87.cc +++ b/deps/v8/src/ic/x87/ic-x87.cc @@ -694,8 +694,8 @@ void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm, __ JumpIfNotUniqueNameInstanceType(ebx, &slow); Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( Code::ComputeHandlerFlags(Code::STORE_IC)); - masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, - key, ebx, no_reg); + masm->isolate()->stub_cache()->GenerateProbe( + masm, Code::STORE_IC, flags, false, receiver, key, ebx, no_reg); // Cache miss. __ jmp(&miss); @@ -769,31 +769,52 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { static void LoadIC_PushArgs(MacroAssembler* masm) { Register receiver = LoadDescriptor::ReceiverRegister(); Register name = LoadDescriptor::NameRegister(); - DCHECK(!ebx.is(receiver) && !ebx.is(name)); + if (FLAG_vector_ics) { + Register slot = VectorLoadICDescriptor::SlotRegister(); + Register vector = VectorLoadICDescriptor::VectorRegister(); + DCHECK(!edi.is(receiver) && !edi.is(name) && !edi.is(slot) && + !edi.is(vector)); + + __ pop(edi); + __ push(receiver); + __ push(name); + __ push(slot); + __ push(vector); + __ push(edi); + } else { + DCHECK(!ebx.is(receiver) && !ebx.is(name)); - __ pop(ebx); - __ push(receiver); - __ push(name); - __ push(ebx); + __ pop(ebx); + __ push(receiver); + __ push(name); + __ push(ebx); + } } void LoadIC::GenerateMiss(MacroAssembler* masm) { // Return address is on the stack. __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); - LoadIC_PushArgs(masm); // Perform tail call to the entry. ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); - __ TailCallExternalReference(ref, 2, 1); + int arg_count = FLAG_vector_ics ? 4 : 2; + __ TailCallExternalReference(ref, arg_count, 1); } void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { // Return address is on the stack. - LoadIC_PushArgs(masm); + Register receiver = LoadDescriptor::ReceiverRegister(); + Register name = LoadDescriptor::NameRegister(); + DCHECK(!ebx.is(receiver) && !ebx.is(name)); + + __ pop(ebx); + __ push(receiver); + __ push(name); + __ push(ebx); // Perform tail call to the entry. __ TailCallRuntime(Runtime::kGetProperty, 2, 1); @@ -809,13 +830,21 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { // Perform tail call to the entry. ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); - __ TailCallExternalReference(ref, 2, 1); + int arg_count = FLAG_vector_ics ? 4 : 2; + __ TailCallExternalReference(ref, arg_count, 1); } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { // Return address is on the stack. - LoadIC_PushArgs(masm); + Register receiver = LoadDescriptor::ReceiverRegister(); + Register name = LoadDescriptor::NameRegister(); + DCHECK(!ebx.is(receiver) && !ebx.is(name)); + + __ pop(ebx); + __ push(receiver); + __ push(name); + __ push(ebx); // Perform tail call to the entry. __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); @@ -827,7 +856,7 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( Code::ComputeHandlerFlags(Code::STORE_IC)); masm->isolate()->stub_cache()->GenerateProbe( - masm, flags, false, StoreDescriptor::ReceiverRegister(), + masm, Code::STORE_IC, flags, false, StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), ebx, no_reg); // Cache miss: Jump to runtime. diff --git a/deps/v8/src/ic/x87/stub-cache-x87.cc b/deps/v8/src/ic/x87/stub-cache-x87.cc index 0291ef3d82..be456ce95c 100644 --- a/deps/v8/src/ic/x87/stub-cache-x87.cc +++ b/deps/v8/src/ic/x87/stub-cache-x87.cc @@ -7,7 +7,9 @@ #if V8_TARGET_ARCH_X87 #include "src/codegen.h" +#include "src/ic/ic.h" #include "src/ic/stub-cache.h" +#include "src/interface-descriptors.h" namespace v8 { namespace internal { @@ -16,7 +18,7 @@ namespace internal { static void ProbeTable(Isolate* isolate, MacroAssembler* masm, - Code::Flags flags, bool leave_frame, + Code::Kind ic_kind, Code::Flags flags, bool leave_frame, StubCache::Table table, Register name, Register receiver, // Number of the cache entry pointer-size scaled. Register offset, Register extra) { @@ -56,6 +58,13 @@ static void ProbeTable(Isolate* isolate, MacroAssembler* masm, } #endif + if (IC::ICUseVector(ic_kind)) { + // The vector and slot were pushed onto the stack before starting the + // probe, and need to be dropped before calling the handler. + __ pop(VectorLoadICDescriptor::VectorRegister()); + __ pop(VectorLoadICDescriptor::SlotRegister()); + } + if (leave_frame) __ leave(); // Jump to the first instruction in the code stub. @@ -100,6 +109,18 @@ static void ProbeTable(Isolate* isolate, MacroAssembler* masm, __ pop(offset); __ mov(offset, Operand::StaticArray(offset, times_1, value_offset)); + if (IC::ICUseVector(ic_kind)) { + // The vector and slot were pushed onto the stack before starting the + // probe, and need to be dropped before calling the handler. + Register vector = VectorLoadICDescriptor::VectorRegister(); + Register slot = VectorLoadICDescriptor::SlotRegister(); + DCHECK(!offset.is(vector) && !offset.is(slot)); + + __ pop(vector); + __ pop(slot); + } + + if (leave_frame) __ leave(); // Jump to the first instruction in the code stub. @@ -113,10 +134,11 @@ static void ProbeTable(Isolate* isolate, MacroAssembler* masm, } -void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags, - bool leave_frame, Register receiver, - Register name, Register scratch, Register extra, - Register extra2, Register extra3) { +void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind, + Code::Flags flags, bool leave_frame, + Register receiver, Register name, + Register scratch, Register extra, Register extra2, + Register extra3) { Label miss; // Assert that code is valid. The multiplying code relies on the entry size @@ -159,8 +181,8 @@ void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags, DCHECK(kCacheIndexShift == kPointerSizeLog2); // Probe the primary table. - ProbeTable(isolate(), masm, flags, leave_frame, kPrimary, name, receiver, - offset, extra); + ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kPrimary, name, + receiver, offset, extra); // Primary miss: Compute hash for secondary probe. __ mov(offset, FieldOperand(name, Name::kHashFieldOffset)); @@ -172,8 +194,8 @@ void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags, __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift); // Probe the secondary table. - ProbeTable(isolate(), masm, flags, leave_frame, kSecondary, name, receiver, - offset, extra); + ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kSecondary, name, + receiver, offset, extra); // Cache miss: Fall-through and let caller handle the miss by // entering the runtime system. |