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.

Reply via email to