Land patch by Pavel Podivilov (podivilov@chromium.org).

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
This commit is contained in:
vitalyr@chromium.org 2010-04-06 14:16:39 +00:00
parent b14a73fc82
commit 9b54227cc7
3 changed files with 70 additions and 1 deletions

View 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);
}

View 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);
}

View 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);
}