[ic] Turn the KeyedLoadIC_IndexedString builtin into a data handler.
This is preparation for supporting OOB loads from strings, which requires the KeyedLoadIC to track this information. Bug: v8:6936, v8:7014 Change-Id: Ide132244ee523397dd418d21fe3377976f6633fd Reviewed-on: https://chromium-review.googlesource.com/743481 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#49026}
This commit is contained in:
parent
563ddadc7a
commit
6f105c7a58
@ -204,7 +204,6 @@ namespace internal {
|
||||
TFH(KeyedLoadIC_Miss, LoadWithVector) \
|
||||
TFH(KeyedLoadIC_PolymorphicName, LoadWithVector) \
|
||||
TFH(KeyedLoadIC_Slow, LoadWithVector) \
|
||||
TFH(KeyedLoadIC_IndexedString, LoadWithVector) \
|
||||
TFH(KeyedStoreIC_Megamorphic, StoreWithVector) \
|
||||
TFH(KeyedStoreIC_Miss, StoreWithVector) \
|
||||
TFH(KeyedStoreIC_Slow, StoreWithVector) \
|
||||
|
@ -20,28 +20,6 @@ TF_BUILTIN(LoadIC_StringLength, CodeStubAssembler) {
|
||||
Return(result);
|
||||
}
|
||||
|
||||
TF_BUILTIN(KeyedLoadIC_IndexedString, CodeStubAssembler) {
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* index = Parameter(Descriptor::kName);
|
||||
Node* slot = Parameter(Descriptor::kSlot);
|
||||
Node* vector = Parameter(Descriptor::kVector);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
Label miss(this);
|
||||
|
||||
Node* index_intptr = TryToIntptr(index, &miss);
|
||||
Node* length = SmiUntag(LoadStringLength(receiver));
|
||||
GotoIf(UintPtrGreaterThanOrEqual(index_intptr, length), &miss);
|
||||
|
||||
Node* code = StringCharCodeAt(receiver, index_intptr, INTPTR_PARAMETERS);
|
||||
Node* result = StringFromCharCode(code);
|
||||
Return(result);
|
||||
|
||||
BIND(&miss);
|
||||
TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, index, slot,
|
||||
vector);
|
||||
}
|
||||
|
||||
TF_BUILTIN(KeyedLoadIC_Miss, CodeStubAssembler) {
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* name = Parameter(Descriptor::kName);
|
||||
|
@ -828,10 +828,10 @@ class RuntimeCallTimer final {
|
||||
V(TestCounter3)
|
||||
|
||||
#define FOR_EACH_HANDLER_COUNTER(V) \
|
||||
V(KeyedLoadIC_LoadIndexedStringStub) \
|
||||
V(KeyedLoadIC_LoadIndexedInterceptorStub) \
|
||||
V(KeyedLoadIC_KeyedLoadSloppyArgumentsStub) \
|
||||
V(KeyedLoadIC_LoadElementDH) \
|
||||
V(KeyedLoadIC_LoadIndexedStringDH) \
|
||||
V(KeyedLoadIC_SlowStub) \
|
||||
V(KeyedStoreIC_ElementsTransitionAndStoreStub) \
|
||||
V(KeyedStoreIC_KeyedStoreSloppyArgumentsStub) \
|
||||
|
@ -216,10 +216,13 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
|
||||
Node* handler_word = SmiUntag(smi_handler);
|
||||
Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word);
|
||||
if (support_elements == kSupportElements) {
|
||||
Label property(this);
|
||||
GotoIfNot(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kElement)),
|
||||
&property);
|
||||
Label if_element(this), if_indexed_string(this), if_property(this);
|
||||
GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kElement)),
|
||||
&if_element);
|
||||
Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kIndexedString)),
|
||||
&if_indexed_string, &if_property);
|
||||
|
||||
BIND(&if_element);
|
||||
Comment("element_load");
|
||||
Node* intptr_index = TryToIntptr(p->name, miss);
|
||||
Node* elements = LoadElements(holder);
|
||||
@ -250,7 +253,18 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
|
||||
exit_point->Return(UndefinedConstant());
|
||||
}
|
||||
|
||||
BIND(&property);
|
||||
BIND(&if_indexed_string);
|
||||
{
|
||||
Comment("indexed string");
|
||||
Node* intptr_index = TryToIntptr(p->name, miss);
|
||||
Node* length = SmiUntag(LoadStringLength(holder));
|
||||
GotoIf(UintPtrGreaterThanOrEqual(intptr_index, length), miss);
|
||||
Node* code = StringCharCodeAt(holder, intptr_index, INTPTR_PARAMETERS);
|
||||
Node* result = StringFromCharCode(code);
|
||||
Return(result);
|
||||
}
|
||||
|
||||
BIND(&if_property);
|
||||
Comment("property_load");
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,11 @@ Handle<Smi> LoadHandler::LoadElement(Isolate* isolate,
|
||||
return handle(Smi::FromInt(config), isolate);
|
||||
}
|
||||
|
||||
Handle<Smi> LoadHandler::LoadIndexedString(Isolate* isolate) {
|
||||
int config = KindBits::encode(kIndexedString);
|
||||
return handle(Smi::FromInt(config), isolate);
|
||||
}
|
||||
|
||||
Handle<Smi> StoreHandler::StoreGlobalProxy(Isolate* isolate) {
|
||||
int config = KindBits::encode(kStoreGlobalProxy);
|
||||
return handle(Smi::FromInt(config), isolate);
|
||||
|
@ -19,6 +19,7 @@ class LoadHandler {
|
||||
public:
|
||||
enum Kind {
|
||||
kElement,
|
||||
kIndexedString,
|
||||
kNormal,
|
||||
kGlobal,
|
||||
kField,
|
||||
@ -159,6 +160,9 @@ class LoadHandler {
|
||||
bool convert_hole_to_undefined,
|
||||
bool is_js_array);
|
||||
|
||||
// Creates a Smi-handler for loading from a String.
|
||||
static inline Handle<Smi> LoadIndexedString(Isolate* isolate);
|
||||
|
||||
private:
|
||||
// Sets DoAccessCheckOnReceiverBits in given Smi-handler. The receiver
|
||||
// check is a part of a prototype chain check.
|
||||
|
@ -1060,11 +1060,11 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map) {
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedInterceptorStub);
|
||||
return LoadIndexedInterceptorStub(isolate()).GetCode();
|
||||
}
|
||||
if (receiver_map->IsStringMap()) {
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedStringStub);
|
||||
return BUILTIN_CODE(isolate(), KeyedLoadIC_IndexedString);
|
||||
}
|
||||
InstanceType instance_type = receiver_map->instance_type();
|
||||
if (instance_type < FIRST_NONSTRING_TYPE) {
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedStringDH);
|
||||
return LoadHandler::LoadIndexedString(isolate());
|
||||
}
|
||||
if (instance_type < FIRST_JS_RECEIVER_TYPE) {
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_SlowStub);
|
||||
return BUILTIN_CODE(isolate(), KeyedLoadIC_Slow);
|
||||
|
Loading…
Reference in New Issue
Block a user