Commit 473280f8 authored by verwaest's avatar verwaest Committed by Commit bot

Create per-descriptor-index LoadApiGetterStub

This avoids custom compilation of receiver handlers for api getters.

BUG=

Review URL: https://codereview.chromium.org/1895093002

Cr-Commit-Position: refs/heads/master@{#35616}
parent 9be47f57
...@@ -17,6 +17,11 @@ Callable CodeFactory::LoadIC(Isolate* isolate, TypeofMode typeof_mode) { ...@@ -17,6 +17,11 @@ Callable CodeFactory::LoadIC(Isolate* isolate, TypeofMode typeof_mode) {
return Callable(stub.GetCode(), LoadDescriptor(isolate)); return Callable(stub.GetCode(), LoadDescriptor(isolate));
} }
// static
Callable CodeFactory::ApiGetter(Isolate* isolate) {
CallApiGetterStub stub(isolate);
return Callable(stub.GetCode(), ApiGetterDescriptor(isolate));
}
// static // static
Callable CodeFactory::LoadICInOptimizedCode( Callable CodeFactory::LoadICInOptimizedCode(
......
...@@ -61,6 +61,8 @@ class CodeFactory final { ...@@ -61,6 +61,8 @@ class CodeFactory final {
static Callable BinaryOpIC(Isolate* isolate, Token::Value op); static Callable BinaryOpIC(Isolate* isolate, Token::Value op);
static Callable ApiGetter(Isolate* isolate);
// Code stubs. Add methods here as needed to reduce dependency on // Code stubs. Add methods here as needed to reduce dependency on
// code-stubs.h. // code-stubs.h.
static Callable InstanceOf(Isolate* isolate); static Callable InstanceOf(Isolate* isolate);
......
...@@ -3229,6 +3229,23 @@ void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) { ...@@ -3229,6 +3229,23 @@ void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) {
} // namespace } // namespace
void LoadApiGetterStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* context = assembler->Parameter(3);
Node* receiver = assembler->Parameter(0);
// For now we only support receiver_is_holder.
DCHECK(receiver_is_holder());
Node* holder = receiver;
Node* map = assembler->LoadMap(receiver);
Node* descriptors = assembler->LoadMapDescriptors(map);
Node* offset =
assembler->Int32Constant(DescriptorArray::ToValueIndex(index()));
Node* callback =
assembler->LoadFixedArrayElementInt32Index(descriptors, offset);
assembler->TailCallStub(CodeFactory::ApiGetter(isolate()), context, receiver,
holder, callback);
}
void LessThanStub::GenerateAssembly(CodeStubAssembler* assembler) const { void LessThanStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateAbstractRelationalComparison(assembler, kLessThan); GenerateAbstractRelationalComparison(assembler, kLessThan);
} }
......
...@@ -140,15 +140,16 @@ namespace internal { ...@@ -140,15 +140,16 @@ namespace internal {
V(ToLength) \ V(ToLength) \
/* IC Handler stubs */ \ /* IC Handler stubs */ \
V(ArrayBufferViewLoadField) \ V(ArrayBufferViewLoadField) \
V(KeyedLoadSloppyArguments) \
V(KeyedStoreSloppyArguments) \
V(LoadApiGetter) \
V(LoadConstant) \ V(LoadConstant) \
V(LoadFastElement) \ V(LoadFastElement) \
V(LoadField) \ V(LoadField) \
V(LoadIndexedInterceptor) \ V(LoadIndexedInterceptor) \
V(KeyedLoadSloppyArguments) \
V(KeyedStoreSloppyArguments) \
V(StoreField) \ V(StoreField) \
V(StoreInterceptor) \
V(StoreGlobal) \ V(StoreGlobal) \
V(StoreInterceptor) \
V(StoreTransition) V(StoreTransition)
// List of code stubs only used on ARM 32 bits platforms. // List of code stubs only used on ARM 32 bits platforms.
...@@ -1456,6 +1457,30 @@ class LoadConstantStub : public HandlerStub { ...@@ -1456,6 +1457,30 @@ class LoadConstantStub : public HandlerStub {
DEFINE_HANDLER_CODE_STUB(LoadConstant, HandlerStub); DEFINE_HANDLER_CODE_STUB(LoadConstant, HandlerStub);
}; };
class LoadApiGetterStub : public TurboFanCodeStub {
public:
LoadApiGetterStub(Isolate* isolate, bool receiver_is_holder, int index)
: TurboFanCodeStub(isolate) {
minor_key_ = IndexBits::encode(index) |
ReceiverIsHolderBits::encode(receiver_is_holder);
}
Code::Kind GetCodeKind() const override { return Code::HANDLER; }
ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
InlineCacheState GetICState() const override { return MONOMORPHIC; }
int index() const { return IndexBits::decode(minor_key_); }
bool receiver_is_holder() const {
return ReceiverIsHolderBits::decode(minor_key_);
}
private:
class ReceiverIsHolderBits : public BitField<bool, 0, 1> {};
class IndexBits : public BitField<int, 1, kDescriptorIndexBitCount> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_TURBOFAN_CODE_STUB(LoadApiGetter, TurboFanCodeStub);
};
class StoreFieldStub : public HandlerStub { class StoreFieldStub : public HandlerStub {
public: public:
......
...@@ -599,6 +599,14 @@ Node* CodeAssembler::TailCallStub(Callable const& callable, Node* context, ...@@ -599,6 +599,14 @@ Node* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
result_size); result_size);
} }
Node* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
Node* arg1, Node* arg2, Node* arg3,
size_t result_size) {
Node* target = HeapConstant(callable.code());
return TailCallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
result_size);
}
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1, Node* target, Node* context, Node* arg1,
Node* arg2, size_t result_size) { Node* arg2, size_t result_size) {
...@@ -615,6 +623,23 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, ...@@ -615,6 +623,23 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
return raw_assembler_->TailCallN(call_descriptor, target, args); return raw_assembler_->TailCallN(call_descriptor, target, args);
} }
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
Node* arg2, Node* arg3, size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(4);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = context;
return raw_assembler_->TailCallN(call_descriptor, target, args);
}
Node* CodeAssembler::TailCallBytecodeDispatch( Node* CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& interface_descriptor, const CallInterfaceDescriptor& interface_descriptor,
Node* code_target_address, Node** args) { Node* code_target_address, Node** args) {
......
...@@ -295,9 +295,14 @@ class CodeAssembler { ...@@ -295,9 +295,14 @@ class CodeAssembler {
Node* TailCallStub(Callable const& callable, Node* context, Node* arg1, Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
Node* arg2, size_t result_size = 1); Node* arg2, size_t result_size = 1);
Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
Node* arg2, Node* arg3, size_t result_size = 1);
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target, Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* context, Node* arg1, Node* arg2,
size_t result_size = 1); size_t result_size = 1);
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* arg3,
size_t result_size = 1);
Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor, Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
Node* code_target_address, Node** args); Node* code_target_address, Node** args);
......
...@@ -1044,8 +1044,9 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1044,8 +1044,9 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
NamedLoadHandlerCompiler compiler(isolate(), map, holder, NamedLoadHandlerCompiler compiler(isolate(), map, holder,
cache_holder); cache_holder);
if (call_optimization.is_simple_api_call()) { if (call_optimization.is_simple_api_call()) {
return compiler.CompileLoadCallback( int index = lookup->GetAccessorIndex();
lookup->name(), call_optimization, lookup->GetAccessorIndex()); return compiler.CompileLoadCallback(lookup->name(),
call_optimization, index);
} }
int expected_arguments = Handle<JSFunction>::cast(getter) int expected_arguments = Handle<JSFunction>::cast(getter)
->shared() ->shared()
...@@ -1054,13 +1055,18 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1054,13 +1055,18 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
lookup->name(), lookup->GetAccessorIndex(), expected_arguments); lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
} else if (accessors->IsAccessorInfo()) { } else if (accessors->IsAccessorInfo()) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
if (v8::ToCData<Address>(info->getter()) == 0) break; if (v8::ToCData<Address>(info->getter()) == nullptr) break;
if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) { if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) {
// This case should be already handled in LoadIC::UpdateCaches. // This case should be already handled in LoadIC::UpdateCaches.
UNREACHABLE(); UNREACHABLE();
break; break;
} }
if (!holder->HasFastProperties()) break; if (!holder->HasFastProperties()) break;
if (receiver_is_holder) {
int index = lookup->GetAccessorIndex();
LoadApiGetterStub stub(isolate(), true, index);
return stub.GetCode();
}
NamedLoadHandlerCompiler compiler(isolate(), map, holder, NamedLoadHandlerCompiler compiler(isolate(), map, holder,
cache_holder); cache_holder);
return compiler.CompileLoadCallback(lookup->name(), info); return compiler.CompileLoadCallback(lookup->name(), info);
......
...@@ -3092,6 +3092,11 @@ class DescriptorArray: public FixedArray { ...@@ -3092,6 +3092,11 @@ class DescriptorArray: public FixedArray {
return kFirstIndex + (descriptor_number * kDescriptorSize) + kDescriptorKey; return kFirstIndex + (descriptor_number * kDescriptorSize) + kDescriptorKey;
} }
static int ToValueIndex(int descriptor_number) {
return kFirstIndex + (descriptor_number * kDescriptorSize) +
kDescriptorValue;
}
private: private:
// An entry in a DescriptorArray, represented as an (array, index) pair. // An entry in a DescriptorArray, represented as an (array, index) pair.
class Entry { class Entry {
...@@ -3107,12 +3112,6 @@ class DescriptorArray: public FixedArray { ...@@ -3107,12 +3112,6 @@ class DescriptorArray: public FixedArray {
int index_; int index_;
}; };
static int ToValueIndex(int descriptor_number) {
return kFirstIndex +
(descriptor_number * kDescriptorSize) +
kDescriptorValue;
}
// Transfer a complete descriptor from the src descriptor array to this // Transfer a complete descriptor from the src descriptor array to this
// descriptor array. // descriptor array.
void CopyFrom(int index, DescriptorArray* src); void CopyFrom(int index, DescriptorArray* src);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment