diff options
Diffstat (limited to 'deps/v8/src/ic/x64/handler-compiler-x64.cc')
-rw-r--r-- | deps/v8/src/ic/x64/handler-compiler-x64.cc | 121 |
1 files changed, 81 insertions, 40 deletions
diff --git a/deps/v8/src/ic/x64/handler-compiler-x64.cc b/deps/v8/src/ic/x64/handler-compiler-x64.cc index a782b088ed..46fa8cc337 100644 --- a/deps/v8/src/ic/x64/handler-compiler-x64.cc +++ b/deps/v8/src/ic/x64/handler-compiler-x64.cc @@ -15,6 +15,28 @@ namespace internal { #define __ ACCESS_MASM(masm) +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. + __ addp(rsp, Immediate(2 * kPointerSize)); +} + + void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( MacroAssembler* masm, Label* miss_label, Register receiver, Handle<Name> name, Register scratch0, Register scratch1) { @@ -56,24 +78,16 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( - MacroAssembler* masm, int index, Register prototype, Label* miss) { - Isolate* isolate = masm->isolate(); - // Get the global function with the given index. - Handle<JSFunction> function( - JSFunction::cast(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); - __ movp(scratch, Operand(rsi, offset)); - __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); - __ Cmp(Operand(scratch, Context::SlotOffset(index)), function); - __ j(not_equal, miss); - + __ movp(result, Operand(rsi, offset)); + __ movp(result, FieldOperand(result, GlobalObject::kNativeContextOffset)); + __ movp(result, Operand(result, Context::SlotOffset(index))); // Load its initial map. The global functions all have initial maps. - __ Move(prototype, Handle<Map>(function->initial_map())); + __ movp(result, + FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); // Load the prototype from the initial map. - __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); + __ movp(result, FieldOperand(result, Map::kPrototypeOffset)); } @@ -324,17 +338,38 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, } -void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap( - Handle<Name> name, Handle<Map> transition) { +void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { __ Move(this->name(), name); - __ Move(StoreTransitionDescriptor::MapRegister(), 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()) { + __ movl(scratch, FieldOperand(map_reg, Map::kBitField3Offset)); + __ andl(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) { - __ Cmp(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); + __ movp(scratch, + FieldOperand(scratch, DescriptorArray::GetValueOffset(descriptor))); + __ cmpp(value_reg, scratch); __ j(not_equal, miss_label); } @@ -413,18 +448,13 @@ Register PropertyHandlerCompiler::CheckPrototypes( reg = holder_reg; // From now on the object will be in holder_reg. __ movp(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; - if (load_prototype_from_map) { - // Save the map in scratch1 for later. - __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); - } + Register map_reg = scratch1; + __ movp(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 @@ -441,11 +471,7 @@ Register PropertyHandlerCompiler::CheckPrototypes( } reg = holder_reg; // From now on the object will be in holder_reg. - if (load_prototype_from_map) { - __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); - } else { - __ Move(reg, prototype); - } + __ movp(reg, FieldOperand(map_reg, Map::kPrototypeOffset)); } // Go to the next object in the prototype chain. @@ -457,8 +483,10 @@ Register PropertyHandlerCompiler::CheckPrototypes( LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); if (depth != 0 || check == CHECK_ALL_MAPS) { - // Check the holder map. - __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); + __ movp(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. @@ -478,6 +506,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); } @@ -576,6 +608,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 @@ -593,6 +626,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( __ ret(0); __ bind(&interceptor_failed); + InterceptorVectorSlotPop(holder_reg); __ Pop(this->name()); __ Pop(holder_reg); if (must_preserve_receiver_reg) { @@ -625,7 +659,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); __ PopReturnAddressTo(scratch1()); __ Push(receiver()); @@ -671,11 +705,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(); - __ Move(result, cell); + Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); + __ LoadWeakValue(result, weak_cell, &miss); __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); // Check for deleted property if property can actually be deleted. @@ -689,6 +727,9 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( Counters* counters = isolate()->counters(); __ IncrementCounter(counters->named_load_global_stub(), 1); + if (IC::ICUseVector(kind())) { + DiscardVectorAndSlot(); + } __ ret(0); FrontendFooter(name, &miss); |