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) {
return Callable(stub.GetCode(), LoadDescriptor(isolate));
}
// static
Callable CodeFactory::ApiGetter(Isolate* isolate) {
CallApiGetterStub stub(isolate);
return Callable(stub.GetCode(), ApiGetterDescriptor(isolate));
}
// static
Callable CodeFactory::LoadICInOptimizedCode(
......
......@@ -61,6 +61,8 @@ class CodeFactory final {
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.h.
static Callable InstanceOf(Isolate* isolate);
......
......@@ -3229,6 +3229,23 @@ void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) {
} // 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 {
GenerateAbstractRelationalComparison(assembler, kLessThan);
}
......
......@@ -140,15 +140,16 @@ namespace internal {
V(ToLength) \
/* IC Handler stubs */ \
V(ArrayBufferViewLoadField) \
V(KeyedLoadSloppyArguments) \
V(KeyedStoreSloppyArguments) \
V(LoadApiGetter) \
V(LoadConstant) \
V(LoadFastElement) \
V(LoadField) \
V(LoadIndexedInterceptor) \
V(KeyedLoadSloppyArguments) \
V(KeyedStoreSloppyArguments) \
V(StoreField) \
V(StoreInterceptor) \
V(StoreGlobal) \
V(StoreInterceptor) \
V(StoreTransition)
// List of code stubs only used on ARM 32 bits platforms.
......@@ -1456,6 +1457,30 @@ class LoadConstantStub : public 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 {
public:
......
......@@ -599,6 +599,14 @@ Node* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
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* target, Node* context, Node* arg1,
Node* arg2, size_t result_size) {
......@@ -615,6 +623,23 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
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(
const CallInterfaceDescriptor& interface_descriptor,
Node* code_target_address, Node** args) {
......
......@@ -295,9 +295,14 @@ class CodeAssembler {
Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
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* context, Node* arg1, Node* arg2,
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* code_target_address, Node** args);
......
......@@ -1044,8 +1044,9 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
NamedLoadHandlerCompiler compiler(isolate(), map, holder,
cache_holder);
if (call_optimization.is_simple_api_call()) {
return compiler.CompileLoadCallback(
lookup->name(), call_optimization, lookup->GetAccessorIndex());
int index = lookup->GetAccessorIndex();
return compiler.CompileLoadCallback(lookup->name(),
call_optimization, index);
}
int expected_arguments = Handle<JSFunction>::cast(getter)
->shared()
......@@ -1054,13 +1055,18 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
} else if (accessors->IsAccessorInfo()) {
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)) {
// This case should be already handled in LoadIC::UpdateCaches.
UNREACHABLE();
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,
cache_holder);
return compiler.CompileLoadCallback(lookup->name(), info);
......
......@@ -3092,6 +3092,11 @@ class DescriptorArray: public FixedArray {
return kFirstIndex + (descriptor_number * kDescriptorSize) + kDescriptorKey;
}
static int ToValueIndex(int descriptor_number) {
return kFirstIndex + (descriptor_number * kDescriptorSize) +
kDescriptorValue;
}
private:
// An entry in a DescriptorArray, represented as an (array, index) pair.
class Entry {
......@@ -3107,12 +3112,6 @@ class DescriptorArray: public FixedArray {
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
// descriptor array.
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