Commit bdf04d99 authored by ishell's avatar ishell Committed by Commit bot

[ic] Support Api getters by data handlers.

BUG=v8:5561

Review-Url: https://codereview.chromium.org/2479373006
Cr-Commit-Position: refs/heads/master@{#40839}
parent 9604b06e
......@@ -5615,8 +5615,17 @@ void CodeStubAssembler::HandleLoadICHandlerCase(
CSA_ASSERT(UintPtrLessThan(
descriptor, LoadAndUntagFixedArrayBaseLength(descriptors)));
#endif
Return(
LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS));
Node* value =
LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS);
Label if_accessor_info(this);
GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word),
&if_accessor_info);
Return(value);
Bind(&if_accessor_info);
Callable callable = CodeFactory::ApiGetter(isolate());
TailCallStub(callable, p->context, p->receiver, holder, value);
}
}
......
......@@ -757,6 +757,8 @@ class RuntimeCallTimer {
V(LoadIC_HandlerCacheHit_Accessor) \
V(LoadIC_HandlerCacheHit_Data) \
V(LoadIC_HandlerCacheHit_Transition) \
V(LoadIC_LoadApiGetterDH) \
V(LoadIC_LoadApiGetterFromPrototypeDH) \
V(LoadIC_LoadApiGetterStub) \
V(LoadIC_LoadCallback) \
V(LoadIC_LoadConstantDH) \
......
......@@ -24,6 +24,15 @@ Handle<Object> LoadHandler::LoadField(Isolate* isolate,
Handle<Object> LoadHandler::LoadConstant(Isolate* isolate, int descriptor) {
int config = KindBits::encode(kForConstants) |
IsAccessorInfoBits::encode(false) |
DescriptorValueIndexBits::encode(
DescriptorArray::ToValueIndex(descriptor));
return handle(Smi::FromInt(config), isolate);
}
Handle<Object> LoadHandler::LoadApiGetter(Isolate* isolate, int descriptor) {
int config = KindBits::encode(kForConstants) |
IsAccessorInfoBits::encode(true) |
DescriptorValueIndexBits::encode(
DescriptorArray::ToValueIndex(descriptor));
return handle(Smi::FromInt(config), isolate);
......
......@@ -35,9 +35,11 @@ class LoadHandler {
// Encoding when KindBits contains kForConstants.
//
class IsAccessorInfoBits
: public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {};
// +2 here is because each descriptor entry occupies 3 slots in array.
class DescriptorValueIndexBits
: public BitField<unsigned, DoNegativeLookupOnReceiverBits::kNext,
: public BitField<unsigned, IsAccessorInfoBits::kNext,
kDescriptorIndexBitCount + 2> {};
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize);
......@@ -87,6 +89,9 @@ class LoadHandler {
// Creates a Smi-handler for loading a constant from fast object.
static inline Handle<Object> LoadConstant(Isolate* isolate, int descriptor);
// Creates a Smi-handler for loading an Api getter property from fast object.
static inline Handle<Object> LoadApiGetter(Isolate* isolate, int descriptor);
// Sets DoAccessCheckOnReceiverBits in given Smi-handler. The receiver
// check is a part of a prototype chain check.
static inline Handle<Object> EnableAccessCheckOnReceiver(
......
......@@ -1365,17 +1365,33 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
}
// Ruled out by IsCompatibleReceiver() above.
DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map));
if (!holder->HasFastProperties()) return slow_stub();
if (receiver_is_holder) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub);
int index = lookup->GetAccessorIndex();
LoadApiGetterStub stub(isolate(), true, index);
return stub.GetCode();
}
if (info->is_sloppy() && !receiver->IsJSReceiver()) {
if (!holder->HasFastProperties() ||
(info->is_sloppy() && !receiver->IsJSReceiver())) {
DCHECK(!holder->HasFastProperties() || !receiver_is_holder);
TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
return slow_stub();
}
if (FLAG_tf_load_ic_stub) {
Handle<Object> smi_handler = LoadHandler::LoadApiGetter(
isolate(), lookup->GetAccessorIndex());
if (receiver_is_holder) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterDH);
return smi_handler;
}
if (kind() != Code::LOAD_GLOBAL_IC) {
TRACE_HANDLER_STATS(isolate(),
LoadIC_LoadApiGetterFromPrototypeDH);
return LoadFromPrototype(map, holder, lookup->name(),
smi_handler);
}
} else {
if (receiver_is_holder) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub);
int index = lookup->GetAccessorIndex();
LoadApiGetterStub stub(isolate(), true, index);
return stub.GetCode();
}
}
break; // Custom-compiled handler.
}
}
......
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