[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:
Benedikt Meurer 2017-10-30 11:17:05 +01:00 committed by Commit Bot
parent 563ddadc7a
commit 6f105c7a58
7 changed files with 32 additions and 32 deletions

View File

@ -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) \

View File

@ -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);

View File

@ -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) \

View File

@ -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");
}

View File

@ -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);

View File

@ -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.

View File

@ -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);