Land patch by Pavel Podivilov (podivilov@chromium.org).
authorvitalyr@chromium.org <vitalyr@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 6 Apr 2010 14:16:39 +0000 (14:16 +0000)
committervitalyr@chromium.org <vitalyr@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 6 Apr 2010 14:16:39 +0000 (14:16 +0000)
Port string stub for keyed loads to x64 and ARM.

BUG=566
TBR=ager@chromium.org
TEST=test/mjsunit/string-index.js

Original code review: http://codereview.chromium.org/1628003

Review URL: http://codereview.chromium.org/1567024

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4348 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/ic-arm.cc
src/x64/ic-x64.cc
test/mjsunit/string-index.js

index cc7cab7..0ac4217 100644 (file)
@@ -706,6 +706,29 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
   //  -- sp[4]  : receiver
   // -----------------------------------
 
+  Label miss, index_ok;
+
+  // Get the key and receiver object from the stack.
+  __ ldm(ia, sp, r0.bit() | r1.bit());
+
+  // Check that the receiver isn't a smi.
+  __ BranchOnSmi(r1, &miss);
+
+  // Check that the receiver is a string.
+  Condition is_string = masm->IsObjectStringType(r1, r2);
+  __ b(NegateCondition(is_string), &miss);
+
+  // Check if key is a smi or a heap number.
+  __ BranchOnSmi(r0, &index_ok);
+  __ CheckMap(r0, r2, Factory::heap_number_map(), &miss, false);
+
+  __ bind(&index_ok);
+  // Duplicate receiver and key since they are expected on the stack after
+  // the KeyedLoadIC call.
+  __ stm(db_w, sp, r0.bit() | r1.bit());
+  __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_JS);
+
+  __ bind(&miss);
   GenerateGeneric(masm);
 }
 
index 7212c05..7bfccd5 100644 (file)
@@ -524,7 +524,32 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
   //  -- rsp[16] : receiver
   // -----------------------------------
 
-  GenerateGeneric(masm);
+  Label miss, index_ok;
+
+  // Check that the receiver isn't a smi.
+  __ movq(rcx, Operand(rsp, 2 * kPointerSize));
+  __ JumpIfSmi(rcx, &miss);
+
+  // Check that the receiver is a string.
+  Condition is_string = masm->IsObjectStringType(rcx, rax, rbx);
+  __ j(NegateCondition(is_string), &miss);
+
+  // Check if key is a smi or a heap number.
+  __ movq(rax, Operand(rsp, kPointerSize));
+  __ JumpIfSmi(rax, &index_ok);
+  __ CheckMap(rax, Factory::heap_number_map(), &miss, false);
+
+  __ bind(&index_ok);
+  // Duplicate receiver and key since they are expected on the stack after
+  // the KeyedLoadIC call.
+  __ pop(rbx);  // return address
+  __ push(rcx);  // receiver
+  __ push(rax);  // key
+  __ push(rbx);  // return address
+  __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_FUNCTION);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
index c6b26a8..3ad71e0 100644 (file)
@@ -166,3 +166,24 @@ for (var i = 1; i < 128; i++) {
   assertEquals(alpha[i], alphaStr[i]);
   assertEquals(String.fromCharCode(i), alphaStr[i]);
 }
+
+// Test for keyed ic.
+var foo = ['a12', ['a', 2, 'c'], 'a31', 42];
+var results = [1, 2, 3, NaN];
+for (var i = 0; i < 200; ++i) {
+  var index = Math.floor(i / 50);
+  var receiver = foo[index];
+  var expected = results[index];
+  var actual = +(receiver[1]);
+  assertEquals(expected, actual);
+}
+
+var keys = [0, '1', 2, 3.0];
+var str = 'abcd', arr = ['a', 'b', 'c', 'd'];
+for (var i = 0; i < 200; ++i) {
+  var index = Math.floor(i / 50);
+  var key = keys[index];
+  var expected = arr[index];
+  var actual = str[key];
+  assertEquals(expected, actual);
+}