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:
parent
b14a73fc82
commit
9b54227cc7
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user