Revision: 24661
Author: [email protected]
Date: Thu Oct 16 11:42:47 2014 UTC
Log: Eliminate special keyed load string stub in favor of uniform
handlers.
KeyedLoadIC installs a special case if the receiver is a string.
Although there are several maps for strings, in practice we seem to
be able to treat them individually because a given KeyedLoad site
only sees 1-2 string types.
[email protected]
Review URL: https://codereview.chromium.org/602773003
https://code.google.com/p/v8/source/detail?r=24661
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm64/code-stubs-arm64.cc
/branches/bleeding_edge/src/builtins.cc
/branches/bleeding_edge/src/builtins.h
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ic/arm/ic-arm.cc
/branches/bleeding_edge/src/ic/arm64/ic-arm64.cc
/branches/bleeding_edge/src/ic/handler-compiler.cc
/branches/bleeding_edge/src/ic/ia32/ic-ia32.cc
/branches/bleeding_edge/src/ic/ic-compiler.cc
/branches/bleeding_edge/src/ic/ic.cc
/branches/bleeding_edge/src/ic/ic.h
/branches/bleeding_edge/src/ic/mips/ic-mips.cc
/branches/bleeding_edge/src/ic/x64/ic-x64.cc
/branches/bleeding_edge/src/mips/code-stubs-mips.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/type-info.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Oct 16 10:38:58
2014 UTC
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Oct 16 11:42:47
2014 UTC
@@ -1501,6 +1501,34 @@
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
}
+
+
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+ // Return address is in lr.
+ Label miss;
+
+ Register receiver = LoadDescriptor::ReceiverRegister();
+ Register index = LoadDescriptor::NameRegister();
+ Register scratch = r3;
+ Register result = r0;
+ DCHECK(!scratch.is(receiver) && !scratch.is(index));
+
+ StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+ &miss, // When not a string.
+ &miss, // When not a number.
+ &miss, // When index out of
range.
+ STRING_INDEX_IS_ARRAY_INDEX,
+ RECEIVER_IS_STRING);
+ char_at_generator.GenerateFast(masm);
+ __ Ret();
+
+ StubRuntimeCallHelper call_helper;
+ char_at_generator.GenerateSlow(masm, call_helper);
+
+ __ bind(&miss);
+ PropertyAccessCompiler::TailCallBuiltin(
+ masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc Thu Oct 16
10:38:58 2014 UTC
+++ /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc Thu Oct 16
11:42:47 2014 UTC
@@ -1420,6 +1420,34 @@
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
}
+
+
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+ // Return address is in lr.
+ Label miss;
+
+ Register receiver = LoadDescriptor::ReceiverRegister();
+ Register index = LoadDescriptor::NameRegister();
+ Register result = x0;
+ Register scratch = x3;
+ DCHECK(!scratch.is(receiver) && !scratch.is(index));
+
+ StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+ &miss, // When not a string.
+ &miss, // When not a number.
+ &miss, // When index out of
range.
+ STRING_INDEX_IS_ARRAY_INDEX,
+ RECEIVER_IS_STRING);
+ char_at_generator.GenerateFast(masm);
+ __ Ret();
+
+ StubRuntimeCallHelper call_helper;
+ char_at_generator.GenerateSlow(masm, call_helper);
+
+ __ Bind(&miss);
+ PropertyAccessCompiler::TailCallBuiltin(
+ masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
void InstanceofStub::Generate(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/builtins.cc Thu Oct 9 14:30:44 2014 UTC
+++ /branches/bleeding_edge/src/builtins.cc Thu Oct 16 11:42:47 2014 UTC
@@ -1277,11 +1277,6 @@
static void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) {
KeyedLoadIC::GenerateGeneric(masm);
}
-
-
-static void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
- KeyedLoadIC::GenerateString(masm);
-}
static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/builtins.h Thu Oct 9 14:30:44 2014 UTC
+++ /branches/bleeding_edge/src/builtins.h Thu Oct 16 11:42:47 2014 UTC
@@ -88,7 +88,6 @@
V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC,
PREMONOMORPHIC, \
kNoExtraICState) \
V(KeyedLoadIC_Generic, KEYED_LOAD_IC, GENERIC,
kNoExtraICState) \
- V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC,
kNoExtraICState) \
\
V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC,
StoreIC::kStrictModeState) \
\
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Wed Oct 8 09:15:09 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.h Thu Oct 16 11:42:47 2014 UTC
@@ -39,6 +39,7 @@
V(KeyedLoadICTrampoline) \
V(LoadICTrampoline) \
V(LoadIndexedInterceptor) \
+ V(LoadIndexedString) \
V(MathPow) \
V(ProfileEntryHook) \
V(RecordWrite) \
@@ -882,6 +883,19 @@
};
+class LoadIndexedStringStub : public PlatformCodeStub {
+ public:
+ explicit LoadIndexedStringStub(Isolate* isolate)
+ : PlatformCodeStub(isolate) {}
+
+ virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
+ virtual Code::StubType GetStubType() { return Code::FAST; }
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+ DEFINE_PLATFORM_CODE_STUB(LoadIndexedString, PlatformCodeStub);
+};
+
+
class HandlerStub : public HydrogenCodeStub {
public:
virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
@@ -1657,6 +1671,15 @@
};
+enum ReceiverCheckMode {
+ // We don't know anything about the receiver.
+ RECEIVER_IS_UNKNOWN,
+
+ // We know the receiver is a string.
+ RECEIVER_IS_STRING
+};
+
+
// Generates code implementing String.prototype.charCodeAt.
//
// Only supports the case when the receiver is a string and the index
@@ -1669,20 +1692,19 @@
// preserved, |scratch| and |result| are clobbered.
class StringCharCodeAtGenerator {
public:
- StringCharCodeAtGenerator(Register object,
- Register index,
- Register result,
- Label* receiver_not_string,
- Label* index_not_number,
+ StringCharCodeAtGenerator(Register object, Register index, Register
result,
+ Label* receiver_not_string, Label*
index_not_number,
Label* index_out_of_range,
- StringIndexFlags index_flags)
+ StringIndexFlags index_flags,
+ ReceiverCheckMode check_mode =
RECEIVER_IS_UNKNOWN)
: object_(object),
index_(index),
result_(result),
receiver_not_string_(receiver_not_string),
index_not_number_(index_not_number),
index_out_of_range_(index_out_of_range),
- index_flags_(index_flags) {
+ index_flags_(index_flags),
+ check_mode_(check_mode) {
DCHECK(!result_.is(object_));
DCHECK(!result_.is(index_));
}
@@ -1714,6 +1736,7 @@
Label* index_out_of_range_;
StringIndexFlags index_flags_;
+ ReceiverCheckMode check_mode_;
Label call_runtime_;
Label index_not_smi_;
@@ -1773,20 +1796,13 @@
// preserved, |scratch1|, |scratch2|, and |result| are clobbered.
class StringCharAtGenerator {
public:
- StringCharAtGenerator(Register object,
- Register index,
- Register scratch,
- Register result,
- Label* receiver_not_string,
- Label* index_not_number,
- Label* index_out_of_range,
- StringIndexFlags index_flags)
- : char_code_at_generator_(object,
- index,
- scratch,
- receiver_not_string,
- index_not_number,
- index_out_of_range,
+ StringCharAtGenerator(Register object, Register index, Register scratch,
+ Register result, Label* receiver_not_string,
+ Label* index_not_number, Label* index_out_of_range,
+ StringIndexFlags index_flags,
+ ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
+ : char_code_at_generator_(object, index, scratch,
receiver_not_string,
+ index_not_number, index_out_of_range,
index_flags),
char_from_code_generator_(scratch, result) {}
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Sep 25 07:16:15
2014 UTC
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Oct 16 11:42:47
2014 UTC
@@ -689,6 +689,37 @@
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
}
+
+
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+ // Return address is on the stack.
+ Label miss;
+
+ Register receiver = LoadDescriptor::ReceiverRegister();
+ Register index = LoadDescriptor::NameRegister();
+ Register scratch = ebx;
+ DCHECK(!scratch.is(receiver) && !scratch.is(index));
+ Register result = eax;
+ DCHECK(!result.is(scratch));
+
+ // TODO(mvstanton): the generator doesn't need to verify that
+ // receiver is a string map, that is done outside the handler.
+ StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+ &miss, // When not a string.
+ &miss, // When not a number.
+ &miss, // When index out of
range.
+ STRING_INDEX_IS_ARRAY_INDEX,
+ RECEIVER_IS_STRING);
+ char_at_generator.GenerateFast(masm);
+ __ ret(0);
+
+ StubRuntimeCallHelper call_helper;
+ char_at_generator.GenerateSlow(masm, call_helper);
+
+ __ bind(&miss);
+ PropertyAccessCompiler::TailCallBuiltin(
+ masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
@@ -2747,14 +2778,16 @@
void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
// If the receiver is a smi trigger the non-string case.
STATIC_ASSERT(kSmiTag == 0);
- __ JumpIfSmi(object_, receiver_not_string_);
+ if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+ __ JumpIfSmi(object_, receiver_not_string_);
- // Fetch the instance type of the receiver into result register.
- __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
- __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
- // If the receiver is not a string trigger the non-string case.
- __ test(result_, Immediate(kIsNotStringMask));
- __ j(not_zero, receiver_not_string_);
+ // Fetch the instance type of the receiver into result register.
+ __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
+ __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
+ // If the receiver is not a string trigger the non-string case.
+ __ test(result_, Immediate(kIsNotStringMask));
+ __ j(not_zero, receiver_not_string_);
+ }
// If the index is non-smi trigger the non-smi case.
STATIC_ASSERT(kSmiTag == 0);
=======================================
--- /branches/bleeding_edge/src/ic/arm/ic-arm.cc Thu Oct 9 14:30:44 2014
UTC
+++ /branches/bleeding_edge/src/ic/arm/ic-arm.cc Thu Oct 16 11:42:47 2014
UTC
@@ -585,32 +585,6 @@
// Now jump to the place where smi keys are handled.
__ jmp(&index_smi);
}
-
-
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // Return address is in lr.
- Label miss;
-
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register index = LoadDescriptor::NameRegister();
- Register scratch = r3;
- Register result = r0;
- DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
- StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
- &miss, // When not a string.
- &miss, // When not a number.
- &miss, // When index out of
range.
- STRING_INDEX_IS_ARRAY_INDEX);
- char_at_generator.GenerateFast(masm);
- __ Ret();
-
- StubRuntimeCallHelper call_helper;
- char_at_generator.GenerateSlow(masm, call_helper);
-
- __ bind(&miss);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/arm64/ic-arm64.cc Thu Oct 9 14:30:44
2014 UTC
+++ /branches/bleeding_edge/src/ic/arm64/ic-arm64.cc Thu Oct 16 11:42:47
2014 UTC
@@ -625,32 +625,6 @@
// Now jump to the place where smi keys are handled.
__ B(&index_smi);
}
-
-
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // Return address is in lr.
- Label miss;
-
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register index = LoadDescriptor::NameRegister();
- Register result = x0;
- Register scratch = x3;
- DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
- StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
- &miss, // When not a string.
- &miss, // When not a number.
- &miss, // When index out of
range.
- STRING_INDEX_IS_ARRAY_INDEX);
- char_at_generator.GenerateFast(masm);
- __ Ret();
-
- StubRuntimeCallHelper call_helper;
- char_at_generator.GenerateSlow(masm, call_helper);
-
- __ Bind(&miss);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/handler-compiler.cc Tue Sep 30 14:54:14
2014 UTC
+++ /branches/bleeding_edge/src/ic/handler-compiler.cc Thu Oct 16 11:42:47
2014 UTC
@@ -415,8 +415,8 @@
Handle<Map> receiver_map = receiver_maps->at(i);
Handle<Code> cached_stub;
- if ((receiver_map->instance_type() & kNotStringTag) == 0) {
- cached_stub = isolate()->builtins()->KeyedLoadIC_String();
+ if (receiver_map->IsStringMap()) {
+ cached_stub = LoadIndexedStringStub(isolate()).GetCode();
} else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
} else {
=======================================
--- /branches/bleeding_edge/src/ic/ia32/ic-ia32.cc Thu Oct 9 14:30:44 2014
UTC
+++ /branches/bleeding_edge/src/ic/ia32/ic-ia32.cc Thu Oct 16 11:42:47 2014
UTC
@@ -474,33 +474,6 @@
// Now jump to the place where smi keys are handled.
__ jmp(&index_smi);
}
-
-
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // Return address is on the stack.
- Label miss;
-
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register index = LoadDescriptor::NameRegister();
- Register scratch = ebx;
- DCHECK(!scratch.is(receiver) && !scratch.is(index));
- Register result = eax;
- DCHECK(!result.is(scratch));
-
- StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
- &miss, // When not a string.
- &miss, // When not a number.
- &miss, // When index out of
range.
- STRING_INDEX_IS_ARRAY_INDEX);
- char_at_generator.GenerateFast(masm);
- __ ret(0);
-
- StubRuntimeCallHelper call_helper;
- char_at_generator.GenerateSlow(masm, call_helper);
-
- __ bind(&miss);
- GenerateMiss(masm);
-}
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/ic/ic-compiler.cc Fri Oct 10 13:27:52 2014
UTC
+++ /branches/bleeding_edge/src/ic/ic-compiler.cc Thu Oct 16 11:42:47 2014
UTC
@@ -96,6 +96,9 @@
Handle<Code> stub;
if (receiver_map->has_indexed_interceptor()) {
stub = LoadIndexedInterceptorStub(isolate).GetCode();
+ } else if (receiver_map->IsStringMap()) {
+ // We have a string.
+ stub = LoadIndexedStringStub(isolate).GetCode();
} else if (receiver_map->has_sloppy_arguments_elements()) {
stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
} else if (receiver_map->has_fast_elements() ||
=======================================
--- /branches/bleeding_edge/src/ic/ic.cc Tue Oct 14 09:59:24 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.cc Thu Oct 16 11:42:47 2014 UTC
@@ -512,15 +512,10 @@
ConstantPoolArray* constant_pool) {
if (IsCleared(target)) return;
- // If the target is the string_stub, then don't clear it. It is the
- // perfect stub if we continue to see strings. Holding this
- // state is not preventing learning new information.
- if (target != *isolate->builtins()->KeyedLoadIC_String()) {
- // Make sure to also clear the map used in inline fast cases. If we
- // do not clear these maps, cached code can keep objects alive
- // through the embedded maps.
- SetTargetAtAddress(address, *pre_monomorphic_stub(isolate),
constant_pool);
- }
+ // Make sure to also clear the map used in inline fast cases. If we
+ // do not clear these maps, cached code can keep objects alive
+ // through the embedded maps.
+ SetTargetAtAddress(address, *pre_monomorphic_stub(isolate),
constant_pool);
}
@@ -1162,14 +1157,11 @@
}
-Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
+Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
Handle<Map> receiver_map(receiver->map(), isolate());
MapHandleList target_receiver_maps;
- if (target().is_identical_to(string_stub())) {
- target_receiver_maps.Add(isolate()->factory()->string_map());
- } else {
- TargetMaps(&target_receiver_maps);
- }
+ TargetMaps(&target_receiver_maps);
+
if (target_receiver_maps.length() == 0) {
return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
}
@@ -1181,9 +1173,10 @@
// monomorphic. If this optimistic assumption is not true, the IC will
// miss again and it will become polymorphic and support both the
// untransitioned and transitioned maps.
- if (state() == MONOMORPHIC && IsMoreGeneralElementsKindTransition(
-
target_receiver_maps.at(0)->elements_kind(),
- receiver->GetElementsKind())) {
+ if (state() == MONOMORPHIC && !receiver->IsString() &&
+ IsMoreGeneralElementsKindTransition(
+ target_receiver_maps.at(0)->elements_kind(),
+ Handle<JSObject>::cast(receiver)->GetElementsKind())) {
return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
}
@@ -1231,11 +1224,9 @@
LoadIC::Load(object,
Handle<Name>::cast(key)),
Object);
} else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
- if (object->IsString() && key->IsNumber()) {
- if (state() == UNINITIALIZED) stub = string_stub();
- } else if (object->IsJSObject()) {
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
- if (!Object::ToSmi(isolate(), key).is_null()) {
+ if (object->IsJSObject() || (object->IsString() && key->IsNumber())) {
+ Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
+ if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) {
stub = LoadElementStub(receiver);
}
}
=======================================
--- /branches/bleeding_edge/src/ic/ic.h Tue Oct 14 13:52:15 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.h Thu Oct 16 11:42:47 2014 UTC
@@ -413,7 +413,6 @@
GenerateMiss(masm);
}
static void GenerateGeneric(MacroAssembler* masm);
- static void GenerateString(MacroAssembler* masm);
// Bit mask to be tested against bit field for the cases when
// generic stub should go into slow case.
@@ -428,16 +427,14 @@
static Handle<Code> pre_monomorphic_stub(Isolate* isolate);
protected:
- Handle<Code> LoadElementStub(Handle<JSObject> receiver);
+ // receiver is HeapObject because it could be a String or a JSObject
+ Handle<Code> LoadElementStub(Handle<HeapObject> receiver);
virtual Handle<Code> pre_monomorphic_stub() const {
return pre_monomorphic_stub(isolate());
}
private:
Handle<Code> generic_stub() const { return generic_stub(isolate()); }
- Handle<Code> string_stub() {
- return isolate()->builtins()->KeyedLoadIC_String();
- }
static void Clear(Isolate* isolate, Address address, Code* target,
ConstantPoolArray* constant_pool);
=======================================
--- /branches/bleeding_edge/src/ic/mips/ic-mips.cc Thu Oct 9 18:09:14 2014
UTC
+++ /branches/bleeding_edge/src/ic/mips/ic-mips.cc Thu Oct 16 11:42:47 2014
UTC
@@ -592,32 +592,6 @@
// Now jump to the place where smi keys are handled.
__ Branch(&index_smi);
}
-
-
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // Return address is in ra.
- Label miss;
-
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register index = LoadDescriptor::NameRegister();
- Register scratch = a3;
- Register result = v0;
- DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
- StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
- &miss, // When not a string.
- &miss, // When not a number.
- &miss, // When index out of
range.
- STRING_INDEX_IS_ARRAY_INDEX);
- char_at_generator.GenerateFast(masm);
- __ Ret();
-
- StubRuntimeCallHelper call_helper;
- char_at_generator.GenerateSlow(masm, call_helper);
-
- __ bind(&miss);
- GenerateMiss(masm);
-}
static void KeyedStoreGenerateGenericHelper(
=======================================
--- /branches/bleeding_edge/src/ic/x64/ic-x64.cc Thu Oct 9 14:30:44 2014
UTC
+++ /branches/bleeding_edge/src/ic/x64/ic-x64.cc Thu Oct 16 11:42:47 2014
UTC
@@ -401,32 +401,6 @@
__ IndexFromHash(rbx, key);
__ jmp(&index_smi);
}
-
-
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // Return address is on the stack.
- Label miss;
-
- Register receiver = LoadDescriptor::ReceiverRegister();
- Register index = LoadDescriptor::NameRegister();
- Register scratch = rbx;
- Register result = rax;
- DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
- StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
- &miss, // When not a string.
- &miss, // When not a number.
- &miss, // When index out of
range.
- STRING_INDEX_IS_ARRAY_INDEX);
- char_at_generator.GenerateFast(masm);
- __ ret(0);
-
- StubRuntimeCallHelper call_helper;
- char_at_generator.GenerateSlow(masm, call_helper);
-
- __ bind(&miss);
- GenerateMiss(masm);
-}
static void KeyedStoreGenerateGenericHelper(
=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Wed Oct 1 11:53:29
2014 UTC
+++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Thu Oct 16 11:42:47
2014 UTC
@@ -1401,6 +1401,34 @@
// Return.
__ Jump(ra);
}
+
+
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+ // Return address is in ra.
+ Label miss;
+
+ Register receiver = LoadDescriptor::ReceiverRegister();
+ Register index = LoadDescriptor::NameRegister();
+ Register scratch = a3;
+ Register result = v0;
+ DCHECK(!scratch.is(receiver) && !scratch.is(index));
+
+ StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+ &miss, // When not a string.
+ &miss, // When not a number.
+ &miss, // When index out of
range.
+ STRING_INDEX_IS_ARRAY_INDEX,
+ RECEIVER_IS_STRING);
+ char_at_generator.GenerateFast(masm);
+ __ Ret();
+
+ StubRuntimeCallHelper call_helper;
+ char_at_generator.GenerateSlow(masm, call_helper);
+
+ __ bind(&miss);
+ PropertyAccessCompiler::TailCallBuiltin(
+ masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
// Uses registers a0 to t0.
=======================================
--- /branches/bleeding_edge/src/objects.h Wed Oct 15 12:22:15 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Thu Oct 16 11:42:47 2014 UTC
@@ -6140,6 +6140,7 @@
bool IsJSObjectMap() {
return instance_type() >= FIRST_JS_OBJECT_TYPE;
}
+ bool IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; }
bool IsJSProxyMap() {
InstanceType type = instance_type();
return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
=======================================
--- /branches/bleeding_edge/src/type-info.cc Fri Oct 10 13:27:52 2014 UTC
+++ /branches/bleeding_edge/src/type-info.cc Thu Oct 16 11:42:47 2014 UTC
@@ -260,12 +260,14 @@
void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
receiver_types->Clear();
- *is_string = false;
- if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) {
- *is_string = true;
- } else {
- CollectReceiverTypes(id, receiver_types);
+ CollectReceiverTypes(id, receiver_types);
+
+ // Are all the receiver maps string maps?
+ bool all_strings = receiver_types->length() > 0;
+ for (int i = 0; i < receiver_types->length(); i++) {
+ all_strings &= receiver_types->at(i)->IsStringMap();
}
+ *is_string = all_strings;
}
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Thu Sep 25 07:16:15
2014 UTC
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Thu Oct 16 11:42:47
2014 UTC
@@ -865,6 +865,34 @@
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
}
+
+
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+ // Return address is on the stack.
+ Label miss;
+
+ Register receiver = LoadDescriptor::ReceiverRegister();
+ Register index = LoadDescriptor::NameRegister();
+ Register scratch = rbx;
+ Register result = rax;
+ DCHECK(!scratch.is(receiver) && !scratch.is(index));
+
+ StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+ &miss, // When not a string.
+ &miss, // When not a number.
+ &miss, // When index out of
range.
+ STRING_INDEX_IS_ARRAY_INDEX,
+ RECEIVER_IS_STRING);
+ char_at_generator.GenerateFast(masm);
+ __ ret(0);
+
+ StubRuntimeCallHelper call_helper;
+ char_at_generator.GenerateSlow(masm, call_helper);
+
+ __ bind(&miss);
+ PropertyAccessCompiler::TailCallBuiltin(
+ masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.