[lazy-accessor-pairs] Don't take the fast paths if the context needs to be switched

This works in the ICs since compiled handlers are not shared anymore.

As drive-by cleanup I also removed custom code to deal with compiled handler sharing for primitive and access-checked objects.

Bug: chromium:759734
Change-Id: Ifb394221c2398f42ea9305acc02845db6004c680
Reviewed-on: https://chromium-review.googlesource.com/738381
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48979}
This commit is contained in:
Toon Verwaest 2017-10-26 17:32:23 +02:00 committed by Commit Bot
parent b4fdce5ae9
commit cb84b6f624
41 changed files with 65 additions and 637 deletions

View File

@ -1483,7 +1483,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- sp[(argc - 1) * 4] : first argument
// -- sp[argc * 4] : receiver
// -- sp[(argc + 1) * 4] : accessor_holder
// -----------------------------------
Register callee = r0;
@ -1531,32 +1530,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(holder);
// enter a new context
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- sp[0] : holder
// -- ...
// -- sp[(FCA::kArgsLength - 1) * 4] : new_target
// -- sp[FCA::kArgsLength * 4] : last argument
// -- ...
// -- sp[(FCA::kArgsLength + argc - 1) * 4] : first argument
// -- sp[(FCA::kArgsLength + argc) * 4] : receiver
// -- sp[(FCA::kArgsLength + argc + 1) * 4] : accessor_holder
// -----------------------------------------------------------
// load context from accessor_holder
Register accessor_holder = context;
__ ldr(accessor_holder,
MemOperand(sp, (FCA::kArgsLength + 1 + argc()) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ ldr(scratch0, FieldMemOperand(accessor_holder, HeapObject::kMapOffset));
__ ldrb(scratch1, FieldMemOperand(scratch0, Map::kBitFieldOffset));
__ tst(scratch1, Operand(1 << Map::kIsConstructor));
__ b(ne, &skip_looking_for_constructor);
__ GetMapConstructor(context, scratch0, scratch0, scratch1);
__ bind(&skip_looking_for_constructor);
__ ldr(context, FieldMemOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// load context from callee
__ ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -1599,7 +1573,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
return_value_offset = 2 + FCA::kReturnValueOffset;
}
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
const int stack_space = argc() + FCA::kArgsLength + 2;
const int stack_space = argc() + FCA::kArgsLength + 1;
MemOperand* stack_space_operand = nullptr;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,

View File

@ -1656,19 +1656,6 @@ void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
JumpIfSmi(value, miss);
}
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp, Register temp2) {
Label done, loop;
ldr(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done);
CompareObjectType(result, temp, temp2, MAP_TYPE);
b(ne, &done);
ldr(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
b(&loop);
bind(&done);
}
void MacroAssembler::CallStub(CodeStub* stub,
Condition cond) {
DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.

View File

@ -730,11 +730,6 @@ class MacroAssembler : public TurboAssembler {
// ---------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done, and |temp2| its instance type.
void GetMapConstructor(Register result, Register map, Register temp,
Register temp2);
// Compare object type for heap object. heap_object contains a non-Smi
// whose object type should be compared with the given type. This both
// sets the flags and leaves the object type in the type_reg register.

View File

@ -1706,7 +1706,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- sp[(argc - 1) * 8] : first argument
// -- sp[argc * 8] : receiver
// -- sp[(argc + 1) * 8] : accessor_holder
// -----------------------------------
Register callee = x0;
@ -1741,35 +1740,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ Push(undef, undef, isolate_reg, holder);
// Enter a new context.
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- sp[0] : holder
// -- ...
// -- sp[(FCA::kArgsLength - 1) * 8] : new_target
// -- sp[FCA::kArgsLength * 8] : last argument
// -- ...
// -- sp[(FCA::kArgsLength + argc - 1) * 8] : first argument
// -- sp[(FCA::kArgsLength + argc) * 8] : receiver
// -- sp[(FCA::kArgsLength + argc + 1) * 8] : accessor_holder
// -----------------------------------------------------------
// Load context from accessor_holder.
Register accessor_holder = context;
Register scratch = undef;
Register scratch2 = callee;
__ Ldr(accessor_holder,
MemOperand(__ StackPointer(),
(FCA::kArgsLength + 1 + argc()) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ Ldr(scratch, FieldMemOperand(accessor_holder, HeapObject::kMapOffset));
__ Ldrb(scratch2, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ Tst(scratch2, Operand(1 << Map::kIsConstructor));
__ B(ne, &skip_looking_for_constructor);
__ GetMapConstructor(context, scratch, scratch, scratch2);
__ Bind(&skip_looking_for_constructor);
__ Ldr(context, FieldMemOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// Load context from callee.
__ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -1817,8 +1788,8 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// The number of arguments might be odd, but will be padded when calling the
// stub. We do not round up stack_space here, this will be done in
// CallApiFunctionAndReturn.
const int stack_space = argc() + FCA::kArgsLength + 2;
DCHECK_EQ((stack_space - argc()) % 2, 0);
const int stack_space = (argc() + 1) + FCA::kArgsLength;
DCHECK_EQ((stack_space - (argc() + 1)) % 2, 0);
const int spill_offset = 1 + kApiStackSpace;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
spill_offset, return_value_operand,

View File

@ -2721,19 +2721,6 @@ void MacroAssembler::LoadElementsKindFromMap(Register result, Register map) {
DecodeField<Map::ElementsKindBits>(result);
}
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp, Register temp2) {
Label done, loop;
Ldr(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
Bind(&loop);
JumpIfSmi(result, &done);
CompareObjectType(result, temp, temp2, MAP_TYPE);
B(ne, &done);
Ldr(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
B(&loop);
Bind(&done);
}
void MacroAssembler::CompareRoot(const Register& obj,
Heap::RootListIndex index) {
UseScratchRegisterScope temps(this);

View File

@ -1892,11 +1892,6 @@ class MacroAssembler : public TurboAssembler {
// ---------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done, and |temp2| its instance type.
void GetMapConstructor(Register result, Register map, Register temp,
Register temp2);
// Compare object type for heap object. heap_object contains a non-Smi
// whose object type should be compared with the given type. This both
// sets the flags and leaves the object type in the type_reg register.

View File

@ -445,7 +445,12 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
isolate());
if (!accessor->IsJSFunction()) {
CallOptimization optimization(accessor);
if (optimization.IsCrossContextLazyAccessorPair(*native_context_,
*map)) {
return false;
}
if (!optimization.is_simple_api_call()) return false;
CallOptimization::HolderLookup lookup;
holder =
optimization.LookupHolderOfExpectedType(receiver_map, &lookup);

View File

@ -1617,8 +1617,7 @@ Reduction JSCallReducer::ReduceCallApiFunction(
CallInterfaceDescriptor cid = stub.GetCallInterfaceDescriptor();
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), cid,
cid.GetStackParameterCount() + argc +
2 /* implicit receiver + accessor_holder */,
cid.GetStackParameterCount() + argc + 1 /* implicit receiver */,
CallDescriptor::kNeedsFrameState, Operator::kNoProperties,
MachineType::AnyTagged(), 1);
ApiFunction api_function(v8::ToCData<Address>(call_handler_info->callback()));
@ -1633,8 +1632,7 @@ Reduction JSCallReducer::ReduceCallApiFunction(
node->InsertInput(graph()->zone(), 3, holder);
node->InsertInput(graph()->zone(), 4,
jsgraph()->ExternalConstant(function_reference));
node->InsertInput(graph()->zone(), 5, holder /* as accessor_holder */);
node->ReplaceInput(6, receiver);
node->ReplaceInput(5, receiver);
NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
return Changed(node);
}

View File

@ -1700,7 +1700,7 @@ Node* JSNativeContextSpecialization::InlineApiCall(
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), call_interface_descriptor,
call_interface_descriptor.GetStackParameterCount() + argc +
1 /* implicit receiver */ + 1 /* accessor holder */,
1 /* implicit receiver */,
CallDescriptor::kNeedsFrameState, Operator::kNoProperties,
MachineType::AnyTagged(), 1);
@ -1712,9 +1712,8 @@ Node* JSNativeContextSpecialization::InlineApiCall(
Node* code = jsgraph()->HeapConstant(stub.GetCode());
// Add CallApiCallbackStub's register argument as well.
Node* inputs[12] = {code, target, data, holder, function_reference,
holder, receiver};
int index = 7 + argc;
Node* inputs[11] = {code, target, data, holder, function_reference, receiver};
int index = 6 + argc;
inputs[index++] = context;
inputs[index++] = frame_state;
inputs[index++] = *effect;
@ -1722,7 +1721,7 @@ Node* JSNativeContextSpecialization::InlineApiCall(
// This needs to stay here because of the edge case described in
// http://crbug.com/675648.
if (value != nullptr) {
inputs[7] = value;
inputs[6] = value;
}
return *effect = *control =

View File

@ -1436,7 +1436,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- esp[argc * 4] : first argument
// -- esp[(argc + 1) * 4] : receiver
// -- esp[(argc + 2) * 4] : accessor_holder
// -----------------------------------
Register callee = edi;
@ -1483,33 +1482,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// enter a new context
Register scratch = call_data;
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- esp[0] : holder
// -- ...
// -- esp[(FCA::kArgsLength - 1) * 4] : new_target
// -- esp[FCA::kArgsLength * 4] : last argument
// -- ...
// -- esp[(FCA::kArgsLength + argc - 1) * 4] : first argument
// -- esp[(FCA::kArgsLength + argc) * 4] : receiver
// -- esp[(FCA::kArgsLength + argc + 1) * 4] : accessor_holder
// -----------------------------------------------------------
// load context from accessor_holder
Register accessor_holder = context;
Register scratch2 = callee;
__ mov(accessor_holder,
MemOperand(esp, (argc() + FCA::kArgsLength + 1) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ mov(scratch, FieldOperand(accessor_holder, HeapObject::kMapOffset));
__ test_b(FieldOperand(scratch, Map::kBitFieldOffset),
Immediate(1 << Map::kIsConstructor));
__ j(not_zero, &skip_looking_for_constructor, Label::kNear);
__ GetMapConstructor(context, scratch, scratch2);
__ bind(&skip_looking_for_constructor);
__ mov(context, FieldOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// load context from callee
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
}
@ -1556,7 +1529,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
return_value_offset = 2 + FCA::kReturnValueOffset;
}
Operand return_value_operand(ebp, return_value_offset * kPointerSize);
const int stack_space = argc() + FCA::kArgsLength + 2;
const int stack_space = argc() + FCA::kArgsLength + 1;
Operand* stack_space_operand = nullptr;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
ApiParameterOperand(1), stack_space,

View File

@ -828,19 +828,6 @@ void MacroAssembler::PopStackHandler() {
}
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp) {
Label done, loop;
mov(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done, Label::kNear);
CmpObjectType(result, MAP_TYPE, temp);
j(not_equal, &done, Label::kNear);
mov(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset));
jmp(&loop);
bind(&done);
}
void MacroAssembler::CallStub(CodeStub* stub) {
DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
call(stub->GetCode(), RelocInfo::CODE_TARGET);

View File

@ -589,13 +589,6 @@ class MacroAssembler : public TurboAssembler {
// Unlink the stack handler on top of the stack from the stack handler chain.
void PopStackHandler();
// ---------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done.
void GetMapConstructor(Register result, Register map, Register temp);
// ---------------------------------------------------------------------------
// Runtime calls

View File

@ -178,7 +178,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
int accessor_index) {
DCHECK(accessor_holder != scratch_in);
DCHECK(receiver != scratch_in);
__ push(accessor_holder);
__ push(receiver);
// Write the arguments to stack frame.
if (is_store) {
@ -258,31 +257,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ ldr(scratch1, NativeContextMemOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
__ cmp(scratch1, scratch2);
if (!compare_native_contexts_only) {
__ b(eq, &done);
// Compare security tokens of current and expected native contexts.
__ ldr(scratch1,
ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ ldr(scratch2,
ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
__ cmp(scratch1, scratch2);
}
__ b(ne, miss);
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -110,7 +110,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
DCHECK(!AreAliased(receiver, scratch));
MacroAssembler::PushPopQueue queue(masm);
queue.Queue(accessor_holder);
queue.Queue(receiver);
// Write the arguments to the stack frame.
if (is_store) {
@ -254,31 +253,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ Ldr(scratch1, NativeContextMemOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
__ Cmp(scratch1, scratch2);
if (!compare_native_contexts_only) {
__ B(eq, &done);
// Compare security tokens of current and expected native contexts.
__ Ldr(scratch1,
ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ Ldr(scratch2,
ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
__ Cmp(scratch1, scratch2);
}
__ B(ne, miss);
__ Bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -20,6 +20,14 @@ CallOptimization::CallOptimization(Handle<Object> function) {
}
}
bool CallOptimization::IsCrossContextLazyAccessorPair(Context* native_context,
Map* holder_map) const {
DCHECK(native_context->IsNativeContext());
if (is_constant_call()) return false;
JSFunction* constructor = JSFunction::cast(holder_map->GetConstructor());
return native_context != constructor->context()->native_context();
}
Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
Handle<Map> object_map, HolderLookup* holder_lookup) const {
DCHECK(is_simple_api_call());

View File

@ -17,6 +17,9 @@ class CallOptimization BASE_EMBEDDED {
public:
explicit CallOptimization(Handle<Object> function);
bool IsCrossContextLazyAccessorPair(Context* native_context,
Map* holder_map) const;
bool is_constant_call() const { return !constant_function_.is_null(); }
Handle<JSFunction> constant_function() const {

View File

@ -50,20 +50,6 @@ Handle<Code> PropertyHandlerCompiler::GetCode(Handle<Name> name) {
Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
Handle<Name> name,
Label* miss) {
if (map()->IsPrimitiveMap() || map()->IsJSGlobalProxyMap()) {
// If the receiver is a global proxy and if we get to this point then
// the compile-time (current) native context has access to global proxy's
// native context. Since access rights revocation is not supported at all,
// we can generate a check that an execution-time native context is either
// the same as compile-time native context or has the same access token.
Handle<Context> native_context = isolate()->native_context();
Handle<WeakCell> weak_cell(native_context->self_weak_cell(), isolate());
bool compare_native_contexts_only = map()->IsPrimitiveMap();
GenerateAccessCheck(weak_cell, scratch1(), scratch2(), miss,
compare_native_contexts_only);
}
// Check that the maps starting from the prototype haven't changed.
return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
miss);
@ -75,12 +61,6 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
Handle<Name> name,
Label* miss) {
if (map()->IsJSGlobalProxyMap()) {
Handle<Context> native_context = isolate()->native_context();
Handle<WeakCell> weak_cell(native_context->self_weak_cell(), isolate());
GenerateAccessCheck(weak_cell, scratch1(), scratch2(), miss, false);
}
return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
miss);
}
@ -115,9 +95,10 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
if (V8_UNLIKELY(FLAG_runtime_stats)) {
GenerateTailCall(masm(), slow_stub);
}
Register holder = Frontend(name);
Register holder_reg = Frontend(name);
GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(),
scratch2(), false, no_reg, holder, accessor_index);
scratch2(), false, no_reg, holder_reg,
accessor_index);
return GetCode(name);
}
@ -138,12 +119,12 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
if (V8_UNLIKELY(FLAG_runtime_stats)) {
GenerateTailCall(masm(), slow_stub);
}
Register holder = Frontend(name);
Register holder_reg = Frontend(name);
if (Descriptor::kPassLastArgsOnStack) {
__ LoadParameterFromStack<Descriptor>(value(), Descriptor::kValue);
}
GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()),
receiver(), scratch2(), true, value(), holder,
receiver(), scratch2(), true, value(), holder_reg,
accessor_index);
return GetCode(name);
}

View File

@ -72,25 +72,12 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler {
Handle<Name> name, Register scratch,
Label* miss);
// Generates check that current native context has the same access rights
// as the given |native_context_cell|.
// If |compare_native_contexts_only| is true then access check is considered
// passed if the execution-time native context is equal to contents of
// |native_context_cell|.
// If |compare_native_contexts_only| is false then access check is considered
// passed if the execution-time native context is equal to contents of
// |native_context_cell| or security tokens of both contexts are equal.
void GenerateAccessCheck(Handle<WeakCell> native_context_cell,
Register scratch1, Register scratch2, Label* miss,
bool compare_native_contexts_only);
// Generates code that verifies that the property holder has not changed
// (checking maps of objects in the prototype chain for fast and global
// objects or doing negative lookup for slow objects, ensures that the
// property cells for global objects are still empty) and checks that the map
// of the holder has not changed. If necessary the function also generates
// code for security check in case of global object holders. Helps to make
// sure that the current IC is still valid.
// of the holder has not changed. Helps to make sure that the current IC is
// still valid.
//
// The scratch and holder registers are always clobbered, but the object
// register is only clobbered if it the same as the holder register. The

View File

@ -117,7 +117,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
kPointerSize));
}
// Write the receiver and arguments to stack frame.
__ push(accessor_holder);
__ push(receiver);
if (is_store) {
DCHECK(!AreAliased(receiver, scratch, store_parameter));
@ -267,29 +266,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ mov(scratch1, NativeContextOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
__ cmp(scratch1, scratch2);
if (!compare_native_contexts_only) {
__ j(equal, &done);
// Compare security tokens of current and expected native contexts.
__ mov(scratch1, ContextOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ mov(scratch2, ContextOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
__ cmp(scratch1, scratch2);
}
__ j(not_equal, miss);
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -782,6 +782,10 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
}
CallOptimization call_optimization(getter);
if (call_optimization.IsCrossContextLazyAccessorPair(
isolate()->raw_native_context(), holder->map())) {
return slow_stub();
}
if (call_optimization.is_simple_api_call()) {
if (!call_optimization.IsCompatibleReceiverMap(map, holder) ||
!holder->HasFastProperties()) {
@ -919,8 +923,8 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup) {
DCHECK(accessors->IsAccessorPair());
DCHECK(holder->HasFastProperties());
DCHECK(!GetHostFunction()->shared()->HasBreakInfo());
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
isolate());
Handle<Object> getter(AccessorPair::cast(*accessors)->getter(), isolate());
CallOptimization call_optimization(getter);
NamedLoadHandlerCompiler compiler(isolate(), map, holder);
DCHECK(call_optimization.is_simple_api_call());
@ -1412,6 +1416,10 @@ Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
return slow_stub();
}
CallOptimization call_optimization(setter);
if (call_optimization.IsCrossContextLazyAccessorPair(
isolate()->raw_native_context(), holder->map())) {
return slow_stub();
}
if (call_optimization.is_simple_api_call()) {
if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
break; // Custom-compiled handler.
@ -1419,6 +1427,8 @@ Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
TRACE_GENERIC_IC("incompatible receiver");
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
return slow_stub();
} else if (setter->IsFunctionTemplateInfo()) {
return slow_stub();
}
break; // Custom-compiled handler.
}
@ -1513,8 +1523,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup) {
}
DCHECK(accessors->IsAccessorPair());
Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
isolate());
Handle<Object> setter(AccessorPair::cast(*accessors)->setter(), isolate());
DCHECK(setter->IsJSFunction() || setter->IsFunctionTemplateInfo());
CallOptimization call_optimization(setter);
NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);

View File

@ -169,7 +169,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
int accessor_index) {
DCHECK(accessor_holder != scratch_in);
DCHECK(receiver != scratch_in);
__ push(accessor_holder);
__ push(receiver);
// Write the arguments to stack frame.
if (is_store) {
@ -248,27 +247,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ lw(scratch1, NativeContextMemOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
if (!compare_native_contexts_only) {
__ Branch(&done, eq, scratch1, Operand(scratch2));
// Compare security tokens of current and expected native contexts.
__ lw(scratch1, ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ lw(scratch2, ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
}
__ Branch(miss, ne, scratch1, Operand(scratch2));
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -169,7 +169,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
int accessor_index) {
DCHECK(accessor_holder != scratch_in);
DCHECK(receiver != scratch_in);
__ push(accessor_holder);
__ push(receiver);
// Write the arguments to stack frame.
if (is_store) {
@ -248,27 +247,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ Ld(scratch1, NativeContextMemOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
if (!compare_native_contexts_only) {
__ Branch(&done, eq, scratch1, Operand(scratch2));
// Compare security tokens of current and expected native contexts.
__ Ld(scratch1, ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ Ld(scratch2, ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
}
__ Branch(miss, ne, scratch1, Operand(scratch2));
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -174,7 +174,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
int accessor_index) {
DCHECK(accessor_holder != scratch_in);
DCHECK(receiver != scratch_in);
__ push(accessor_holder);
__ push(receiver);
// Write the arguments to stack frame.
if (is_store) {
@ -254,31 +253,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ LoadP(scratch1, NativeContextMemOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
__ cmp(scratch1, scratch2);
if (!compare_native_contexts_only) {
__ beq(&done);
// Compare security tokens of current and expected native contexts.
__ LoadP(scratch1,
ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ LoadP(scratch2,
ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
__ cmp(scratch1, scratch2);
}
__ bne(miss);
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -167,7 +167,6 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
int accessor_index) {
DCHECK(accessor_holder != scratch_in);
DCHECK(receiver != scratch_in);
__ Push(accessor_holder);
__ Push(receiver);
// Write the arguments to stack frame.
if (is_store) {
@ -246,31 +245,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ LoadP(scratch1, NativeContextMemOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
__ CmpP(scratch1, scratch2);
if (!compare_native_contexts_only) {
__ beq(&done);
// Compare security tokens of current and expected native contexts.
__ LoadP(scratch1,
ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ LoadP(scratch2,
ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
__ CmpP(scratch1, scratch2);
}
__ bne(miss);
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -92,10 +92,9 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
int accessor_index) {
DCHECK(accessor_holder != scratch);
DCHECK(optimization.is_simple_api_call());
Isolate* isolate = masm->isolate();
__ PopReturnAddressTo(scratch);
// accessor_holder
__ Push(accessor_holder);
// receiver
__ Push(receiver);
// Write the arguments to stack frame.
@ -110,7 +109,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
// Abi for CallApiCallbackStub.
Register callee = rdi;
Register data = rbx;
Register holder = rcx;
Register holder_reg = rcx;
Register api_function_address = rdx;
scratch = no_reg;
@ -123,18 +122,17 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
switch (holder_lookup) {
case CallOptimization::kHolderIsReceiver:
__ Move(holder, receiver);
__ Move(holder_reg, receiver);
break;
case CallOptimization::kHolderFound:
__ movp(holder, FieldOperand(receiver, HeapObject::kMapOffset));
__ movp(holder, FieldOperand(holder, Map::kPrototypeOffset));
__ movp(holder_reg, FieldOperand(receiver, HeapObject::kMapOffset));
__ movp(holder_reg, FieldOperand(holder_reg, Map::kPrototypeOffset));
break;
case CallOptimization::kHolderNotFound:
UNREACHABLE();
break;
}
Isolate* isolate = masm->isolate();
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
// Put call data in place.
if (api_call_info->data()->IsUndefined(isolate)) {
@ -250,29 +248,6 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
}
}
void PropertyHandlerCompiler::GenerateAccessCheck(
Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2,
Label* miss, bool compare_native_contexts_only) {
Label done;
// Load current native context.
__ movp(scratch1, NativeContextOperand());
// Load expected native context.
__ LoadWeakValue(scratch2, native_context_cell, miss);
__ cmpp(scratch1, scratch2);
if (!compare_native_contexts_only) {
__ j(equal, &done);
// Compare security tokens of current and expected native contexts.
__ movp(scratch1, ContextOperand(scratch1, Context::SECURITY_TOKEN_INDEX));
__ movp(scratch2, ContextOperand(scratch2, Context::SECURITY_TOKEN_INDEX));
__ cmpp(scratch1, scratch2);
}
__ j(not_equal, miss);
__ bind(&done);
}
Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss) {

View File

@ -1585,7 +1585,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- sp[(argc - 1)* 4] : first argument
// -- sp[argc * 4] : receiver
// -- sp[(argc + 1)* 4] : accessor_holder
// -----------------------------------
Register callee = a0;
@ -1621,33 +1620,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ Push(scratch, holder);
// Enter a new context
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- sp[0] : holder
// -- ...
// -- sp[(FCA::kArgsLength - 1) * 4] : new_target
// -- sp[FCA::kArgsLength * 4] : last argument
// -- ...
// -- sp[(FCA::kArgsLength + argc - 1) * 4] : first argument
// -- sp[(FCA::kArgsLength + argc) * 4] : receiver
// -- sp[(FCA::kArgsLength + argc + 1) * 4] : accessor_holder
// -----------------------------------------------------------
// Load context from accessor_holder
Register accessor_holder = context;
Register scratch2 = callee;
__ lw(accessor_holder,
MemOperand(sp, (FCA::kArgsLength + 1 + argc()) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ lw(scratch, FieldMemOperand(accessor_holder, HeapObject::kMapOffset));
__ lbu(scratch2, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ And(scratch2, scratch2, Operand(1 << Map::kIsConstructor));
__ Branch(&skip_looking_for_constructor, ne, scratch2, Operand(zero_reg));
__ GetMapConstructor(context, scratch, scratch, scratch2);
__ bind(&skip_looking_for_constructor);
__ lw(context, FieldMemOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// Load context from callee.
__ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -1689,7 +1662,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
return_value_offset = 2 + FCA::kReturnValueOffset;
}
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
const int stack_space = argc() + FCA::kArgsLength + 2;
const int stack_space = argc() + FCA::kArgsLength + 1;
// TODO(adamk): Why are we clobbering this immediately?
const int32_t stack_space_offset = kInvalidStackOffset;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,

View File

@ -4174,19 +4174,6 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
// ---------------------------------------------------------------------------
// Support functions.
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp, Register temp2) {
Label done, loop;
lw(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done);
GetObjectType(result, temp, temp2);
Branch(&done, ne, temp2, Operand(MAP_TYPE));
lw(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
Branch(&loop);
bind(&done);
}
void MacroAssembler::GetObjectType(Register object,
Register map,
Register type_reg) {

View File

@ -1088,11 +1088,6 @@ class MacroAssembler : public TurboAssembler {
// -------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done, and |temp2| its instance type.
void GetMapConstructor(Register result, Register map, Register temp,
Register temp2);
void GetObjectType(Register function,
Register map,
Register type_reg);

View File

@ -1587,7 +1587,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- sp[(argc - 1) * 8] : first argument
// -- sp[argc * 8] : receiver
// -- sp[(argc + 1) * 8] : accessor_holder
// -----------------------------------
Register callee = a0;
@ -1623,33 +1622,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ Push(scratch, holder);
// Enter a new context
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- sp[0] : holder
// -- ...
// -- sp[(FCA::kArgsLength - 1) * 8] : new_target
// -- sp[FCA::kArgsLength * 8] : last argument
// -- ...
// -- sp[(FCA::kArgsLength + argc - 1) * 8] : first argument
// -- sp[(FCA::kArgsLength + argc) * 8] : receiver
// -- sp[(FCA::kArgsLength + argc + 1) * 8] : accessor_holder
// -----------------------------------------------------------
// Load context from accessor_holder
Register accessor_holder = context;
Register scratch2 = callee;
__ Ld(accessor_holder,
MemOperand(sp, (FCA::kArgsLength + 1 + argc()) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ Ld(scratch, FieldMemOperand(accessor_holder, HeapObject::kMapOffset));
__ Lbu(scratch2, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ And(scratch2, scratch2, Operand(1 << Map::kIsConstructor));
__ Branch(&skip_looking_for_constructor, ne, scratch2, Operand(zero_reg));
__ GetMapConstructor(context, scratch, scratch, scratch2);
__ bind(&skip_looking_for_constructor);
__ Ld(context, FieldMemOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// Load context from callee.
__ Ld(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -1694,7 +1667,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
return_value_offset = 2 + FCA::kReturnValueOffset;
}
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
const int stack_space = argc() + FCA::kArgsLength + 2;
const int stack_space = argc() + FCA::kArgsLength + 1;
// TODO(adamk): Why are we clobbering this immediately?
const int32_t stack_space_offset = kInvalidStackOffset;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,

View File

@ -4452,19 +4452,6 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
// ---------------------------------------------------------------------------
// Support functions.
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp, Register temp2) {
Label done, loop;
ld(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done);
GetObjectType(result, temp, temp2);
Branch(&done, ne, temp2, Operand(MAP_TYPE));
ld(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
Branch(&loop);
bind(&done);
}
void MacroAssembler::GetObjectType(Register object,
Register map,
Register type_reg) {

View File

@ -1167,11 +1167,6 @@ class MacroAssembler : public TurboAssembler {
// -------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done, and |temp2| its instance type.
void GetMapConstructor(Register result, Register map, Register temp,
Register temp2);
void GetObjectType(Register function,
Register map,
Register type_reg);

View File

@ -1592,7 +1592,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- sp[(argc - 1)* 4] : first argument
// -- sp[argc * 4] : receiver
// -- sp[(argc + 1)* 4] : accessor_holder
// -----------------------------------
Register callee = r3;
@ -1638,33 +1637,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(holder);
// Enter a new context
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- sp[0] : holder
// -- ...
// -- sp[(FCA::kArgsLength - 1) * 4] : new_target
// -- sp[FCA::kArgsLength * 4] : last argument
// -- ...
// -- sp[(FCA::kArgsLength + argc - 1) * 4] : first argument
// -- sp[(FCA::kArgsLength + argc) * 4] : receiver
// -- sp[(FCA::kArgsLength + argc + 1) * 4] : accessor_holder
// -----------------------------------------------------------
// Load context from accessor_holder
Register accessor_holder = context;
Register scratch2 = callee;
__ LoadP(accessor_holder,
MemOperand(sp, (FCA::kArgsLength + 1 + argc()) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ LoadP(scratch, FieldMemOperand(accessor_holder, HeapObject::kMapOffset));
__ lbz(scratch2, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ andi(r0, scratch2, Operand(1 << Map::kIsConstructor));
__ bne(&skip_looking_for_constructor, cr0);
__ GetMapConstructor(context, scratch, scratch, scratch2);
__ bind(&skip_looking_for_constructor);
__ LoadP(context, FieldMemOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// Load context from callee
__ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -1713,7 +1686,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
return_value_offset = 2 + FCA::kReturnValueOffset;
}
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
const int stack_space = argc() + FCA::kArgsLength + 2;
const int stack_space = argc() + FCA::kArgsLength + 1;
MemOperand* stack_space_operand = nullptr;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,

View File

@ -1527,19 +1527,6 @@ void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
JumpIfSmi(value, miss);
}
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp, Register temp2) {
Label done, loop;
LoadP(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done);
CompareObjectType(result, temp, temp2, MAP_TYPE);
bne(&done);
LoadP(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
b(&loop);
bind(&done);
}
void MacroAssembler::CallStub(CodeStub* stub, Condition cond) {
DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond);

View File

@ -862,11 +862,6 @@ class MacroAssembler : public TurboAssembler {
// ---------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done, and |temp2| its instance type.
void GetMapConstructor(Register result, Register map, Register temp,
Register temp2);
// Compare object type for heap object. heap_object contains a non-Smi
// whose object type should be compared with the given type. This both
// sets the flags and leaves the object type in the type_reg register.

View File

@ -1593,7 +1593,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- sp[(argc - 1) * 4] : first argument
// -- sp[argc * 4] : receiver
// -- sp[(argc + 1) * 4] : accessor_holder
// -----------------------------------
Register callee = r2;
@ -1639,33 +1638,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(holder);
// Enter a new context
if (is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- sp[0] : holder
// -- ...
// -- sp[(FCA::kArgsLength - 1) * 4] : new_target
// -- sp[FCA::kArgsLength * 4] : last argument
// -- ...
// -- sp[(FCA::kArgsLength + argc - 1) * 4] : first argument
// -- sp[(FCA::kArgsLength + argc) * 4] : receiver
// -- sp[(FCA::kArgsLength + argc + 1) * 4] : accessor_holder
// -----------------------------------------------------------
// Load context from accessor_holder
Register accessor_holder = context;
Register scratch2 = callee;
__ LoadP(accessor_holder,
MemOperand(sp, (FCA::kArgsLength + 1 + argc()) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ LoadP(scratch, FieldMemOperand(accessor_holder, HeapObject::kMapOffset));
__ LoadlB(scratch2, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ AndP(scratch2, Operand(1 << Map::kIsConstructor));
__ bne(&skip_looking_for_constructor, Label::kNear);
__ GetMapConstructor(context, scratch, scratch, scratch2);
__ bind(&skip_looking_for_constructor);
__ LoadP(context, FieldMemOperand(context, JSFunction::kContextOffset));
} else {
if (!is_lazy()) {
// Load context from callee
__ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -1714,7 +1687,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
return_value_offset = 2 + FCA::kReturnValueOffset;
}
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
const int stack_space = argc() + FCA::kArgsLength + 2;
const int stack_space = argc() + FCA::kArgsLength + 1;
MemOperand* stack_space_operand = nullptr;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,

View File

@ -1459,19 +1459,6 @@ void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
JumpIfSmi(value, miss);
}
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp, Register temp2) {
Label done, loop;
LoadP(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done);
CompareObjectType(result, temp, temp2, MAP_TYPE);
bne(&done);
LoadP(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
b(&loop);
bind(&done);
}
void MacroAssembler::CallStub(CodeStub* stub, Condition cond) {
DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond);

View File

@ -1065,11 +1065,6 @@ class MacroAssembler : public TurboAssembler {
// ---------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done, and |temp2| its instance type.
void GetMapConstructor(Register result, Register map, Register temp,
Register temp2);
// Compare object type for heap object. heap_object contains a non-Smi
// whose object type should be compared with the given type. This both
// sets the flags and leaves the object type in the type_reg register.

View File

@ -1483,7 +1483,6 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// -- ...
// -- rsp[argc * 8] : first argument
// -- rsp[(argc + 1) * 8] : receiver
// -- rsp[(argc + 2) * 8] : accessor_holder
// -----------------------------------
Register callee = rdi;
@ -1532,33 +1531,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// enter a new context
int argc = this->argc();
if (this->is_lazy()) {
// ----------- S t a t e -------------------------------------
// -- rsp[0] : holder
// -- ...
// -- rsp[(FCA::kArgsLength - 1) * 8] : new_target
// -- rsp[FCA::kArgsLength * 8] : last argument
// -- ...
// -- rsp[(FCA::kArgsLength + argc - 1) * 8] : first argument
// -- rsp[(FCA::kArgsLength + argc) * 8] : receiver
// -- rsp[(FCA::kArgsLength + argc + 1) * 8] : accessor_holder
// -----------------------------------------------------------
// load context from accessor_holder
Register accessor_holder = context;
Register scratch2 = callee;
__ movp(accessor_holder,
MemOperand(rsp, (argc + FCA::kArgsLength + 1) * kPointerSize));
// Look for the constructor if |accessor_holder| is not a function.
Label skip_looking_for_constructor;
__ movp(scratch, FieldOperand(accessor_holder, HeapObject::kMapOffset));
__ testb(FieldOperand(scratch, Map::kBitFieldOffset),
Immediate(1 << Map::kIsConstructor));
__ j(not_zero, &skip_looking_for_constructor, Label::kNear);
__ GetMapConstructor(context, scratch, scratch2);
__ bind(&skip_looking_for_constructor);
__ movp(context, FieldOperand(context, JSFunction::kContextOffset));
} else {
if (!this->is_lazy()) {
// load context from callee
__ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
}
@ -1606,7 +1579,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
FCA::kArgsLength - FCA::kContextSaveIndex);
Operand return_value_operand = args_from_rbp.GetArgumentOperand(
this->is_store() ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
const int stack_space = argc + FCA::kArgsLength + 2;
const int stack_space = argc + FCA::kArgsLength + 1;
Operand* stack_space_operand = nullptr;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, callback_arg,
stack_space, stack_space_operand,

View File

@ -2180,19 +2180,6 @@ void MacroAssembler::AssertUndefinedOrAllocationSite(Register object) {
}
}
void MacroAssembler::GetMapConstructor(Register result, Register map,
Register temp) {
Label done, loop;
movp(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset));
bind(&loop);
JumpIfSmi(result, &done, Label::kNear);
CmpObjectType(result, MAP_TYPE, temp);
j(not_equal, &done, Label::kNear);
movp(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset));
jmp(&loop);
bind(&done);
}
void MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
DCHECK_GT(value, 0);
if (FLAG_native_code_counters && counter->Enabled()) {

View File

@ -910,10 +910,6 @@ class MacroAssembler : public TurboAssembler {
// ---------------------------------------------------------------------------
// Support functions.
// Machine code version of Map::GetConstructor().
// |temp| holds |result|'s map when done.
void GetMapConstructor(Register result, Register map, Register temp);
// Load the global proxy from the current context.
void LoadGlobalProxy(Register dst) {
LoadNativeContextSlot(Context::GLOBAL_PROXY_INDEX, dst);

View File

@ -37,10 +37,7 @@ TEST_F(ObjectTest, SetAccessorWhenUnconfigurablePropAlreadyDefined) {
using LapContextTest = TestWithIsolate;
// TODO(yukishiino): Enable this unittest once
// PropertyAccessInfo::accessor_holder() gets supported. Currently we're using
// PropertyAccessInfo::holder(), which doesn't return the accessor holder.
TEST_F(LapContextTest, DISABLED_CurrentContextInLazyAccessorOnPrototype) {
TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPrototype) {
// The receiver object is created in |receiver_context|, but its prototype
// object is created in |prototype_context|, and the property is accessed
// from |caller_context|.