Port string keyed load IC improvements (r4444) to ARM.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4573 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5affd79e
This diff is collapsed.
...@@ -665,34 +665,66 @@ class GenericBinaryOpStub : public CodeStub { ...@@ -665,34 +665,66 @@ class GenericBinaryOpStub : public CodeStub {
}; };
class StringStubBase: public CodeStub { class StringHelper : public AllStatic {
public: public:
// Generates fast code for getting a char code out of a string
// object at the given index. May bail out for four reasons (in the
// listed order):
// * Receiver is not a string (receiver_not_string label).
// * Index is not a smi (index_not_smi label).
// * Index is out of range (index_out_of_range).
// * Some other reason (slow_case label). In this case it's
// guaranteed that the above conditions are not violated,
// e.g. it's safe to assume the receiver is a string and the
// index is a non-negative smi < length.
// When successful, object, index, and scratch are clobbered.
// Otherwise, scratch and result are clobbered.
static void GenerateFastCharCodeAt(MacroAssembler* masm,
Register object,
Register index,
Register scratch,
Register result,
Label* receiver_not_string,
Label* index_not_smi,
Label* index_out_of_range,
Label* slow_case);
// Generates code for creating a one-char string from the given char
// code. May do a runtime call, so any register can be clobbered
// and, if the given invoke flag specifies a call, an internal frame
// is required. In tail call mode the result must be r0 register.
static void GenerateCharFromCode(MacroAssembler* masm,
Register code,
Register scratch,
Register result,
InvokeFlag flag);
// Generate code for copying characters using a simple loop. This should only // Generate code for copying characters using a simple loop. This should only
// be used in places where the number of characters is small and the // be used in places where the number of characters is small and the
// additional setup and checking in GenerateCopyCharactersLong adds too much // additional setup and checking in GenerateCopyCharactersLong adds too much
// overhead. Copying of overlapping regions is not supported. // overhead. Copying of overlapping regions is not supported.
// Dest register ends at the position after the last character written. // Dest register ends at the position after the last character written.
void GenerateCopyCharacters(MacroAssembler* masm, static void GenerateCopyCharacters(MacroAssembler* masm,
Register dest, Register dest,
Register src, Register src,
Register count, Register count,
Register scratch, Register scratch,
bool ascii); bool ascii);
// Generate code for copying a large number of characters. This function // Generate code for copying a large number of characters. This function
// is allowed to spend extra time setting up conditions to make copying // is allowed to spend extra time setting up conditions to make copying
// faster. Copying of overlapping regions is not supported. // faster. Copying of overlapping regions is not supported.
// Dest register ends at the position after the last character written. // Dest register ends at the position after the last character written.
void GenerateCopyCharactersLong(MacroAssembler* masm, static void GenerateCopyCharactersLong(MacroAssembler* masm,
Register dest, Register dest,
Register src, Register src,
Register count, Register count,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Register scratch3, Register scratch3,
Register scratch4, Register scratch4,
Register scratch5, Register scratch5,
int flags); int flags);
// Probe the symbol table for a two character string. If the string is // Probe the symbol table for a two character string. If the string is
...@@ -702,27 +734,30 @@ class StringStubBase: public CodeStub { ...@@ -702,27 +734,30 @@ class StringStubBase: public CodeStub {
// Contents of both c1 and c2 registers are modified. At the exit c1 is // Contents of both c1 and c2 registers are modified. At the exit c1 is
// guaranteed to contain halfword with low and high bytes equal to // guaranteed to contain halfword with low and high bytes equal to
// initial contents of c1 and c2 respectively. // initial contents of c1 and c2 respectively.
void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
Register c1, Register c1,
Register c2, Register c2,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Register scratch3, Register scratch3,
Register scratch4, Register scratch4,
Register scratch5, Register scratch5,
Label* not_found); Label* not_found);
// Generate string hash. // Generate string hash.
void GenerateHashInit(MacroAssembler* masm, static void GenerateHashInit(MacroAssembler* masm,
Register hash, Register hash,
Register character); Register character);
static void GenerateHashAddCharacter(MacroAssembler* masm,
Register hash,
Register character);
void GenerateHashAddCharacter(MacroAssembler* masm, static void GenerateHashGetHash(MacroAssembler* masm,
Register hash, Register hash);
Register character);
void GenerateHashGetHash(MacroAssembler* masm, private:
Register hash); DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
}; };
...@@ -733,7 +768,7 @@ enum StringAddFlags { ...@@ -733,7 +768,7 @@ enum StringAddFlags {
}; };
class StringAddStub: public StringStubBase { class StringAddStub: public CodeStub {
public: public:
explicit StringAddStub(StringAddFlags flags) { explicit StringAddStub(StringAddFlags flags) {
string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0); string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
...@@ -750,7 +785,7 @@ class StringAddStub: public StringStubBase { ...@@ -750,7 +785,7 @@ class StringAddStub: public StringStubBase {
}; };
class SubStringStub: public StringStubBase { class SubStringStub: public CodeStub {
public: public:
SubStringStub() {} SubStringStub() {}
......
...@@ -800,28 +800,67 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { ...@@ -800,28 +800,67 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss;
Label miss, index_ok; Label index_not_smi;
Label index_out_of_range;
Label slow_char_code;
Label got_char_code;
// Get the key and receiver object from the stack. // Get the key and receiver object from the stack.
__ ldm(ia, sp, r0.bit() | r1.bit()); __ ldm(ia, sp, r0.bit() | r1.bit());
// Check that the receiver isn't a smi. Register object = r1;
__ BranchOnSmi(r1, &miss); Register index = r0;
Register code = r2;
// Check that the receiver is a string. Register scratch = r3;
Condition is_string = masm->IsObjectStringType(r1, r2);
__ b(NegateCondition(is_string), &miss);
// Check if key is a smi or a heap number. StringHelper::GenerateFastCharCodeAt(masm,
__ BranchOnSmi(r0, &index_ok); object,
__ CheckMap(r0, r2, Factory::heap_number_map(), &miss, false); index,
scratch,
code,
&miss, // When not a string.
&index_not_smi,
&index_out_of_range,
&slow_char_code);
// If we didn't bail out, code register contains smi tagged char
// code.
__ bind(&got_char_code);
StringHelper::GenerateCharFromCode(masm, code, scratch, r0, JUMP_FUNCTION);
#ifdef DEBUG
__ Abort("Unexpected fall-through from char from code tail call");
#endif
// Check if key is a heap number.
__ bind(&index_not_smi);
__ CheckMap(index, scratch, Factory::heap_number_map(), &miss, true);
// Push receiver and key on the stack (now that we know they are a
// string and a number), and call runtime.
__ bind(&slow_char_code);
__ EnterInternalFrame();
__ Push(object, index);
__ CallRuntime(Runtime::kStringCharCodeAt, 2);
ASSERT(!code.is(r0));
__ mov(code, r0);
__ LeaveInternalFrame();
__ bind(&index_ok); // Check if the runtime call returned NaN char code. If yes, return
// Duplicate receiver and key since they are expected on the stack after // undefined. Otherwise, we can continue.
// the KeyedLoadIC call. if (FLAG_debug_code) {
__ Push(r1, r0); __ BranchOnSmi(code, &got_char_code);
__ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_JS); __ ldr(scratch, FieldMemOperand(code, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
__ cmp(scratch, ip);
__ Assert(eq, "StringCharCodeAt must return smi or heap number");
}
__ LoadRoot(scratch, Heap::kNanValueRootIndex);
__ cmp(code, scratch);
__ b(ne, &got_char_code);
__ bind(&index_out_of_range);
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
__ Ret();
__ bind(&miss); __ bind(&miss);
GenerateGeneric(masm); GenerateGeneric(masm);
......
...@@ -164,8 +164,7 @@ enum BuiltinExtraArguments { ...@@ -164,8 +164,7 @@ enum BuiltinExtraArguments {
V(STRING_ADD_LEFT, 1) \ V(STRING_ADD_LEFT, 1) \
V(STRING_ADD_RIGHT, 1) \ V(STRING_ADD_RIGHT, 1) \
V(APPLY_PREPARE, 1) \ V(APPLY_PREPARE, 1) \
V(APPLY_OVERFLOW, 1) \ V(APPLY_OVERFLOW, 1)
V(STRING_CHAR_AT, 1)
class ObjectVisitor; class ObjectVisitor;
......
...@@ -471,17 +471,6 @@ function TO_STRING() { ...@@ -471,17 +471,6 @@ function TO_STRING() {
} }
// Specialized version of String.charAt. It assumes string as
// the receiver type and that the index is a number.
function STRING_CHAR_AT(pos) {
var char_code = %_FastCharCodeAt(this, pos);
if (!%_IsSmi(char_code)) {
return %StringCharAt(this, pos);
}
return %_CharFromCode(char_code);
}
/* ------------------------------------- /* -------------------------------------
- - - C o n v e r s i o n s - - - - - - C o n v e r s i o n s - - -
------------------------------------- -------------------------------------
......
...@@ -873,19 +873,19 @@ class StringHelper : public AllStatic { ...@@ -873,19 +873,19 @@ class StringHelper : public AllStatic {
// additional setup and checking in GenerateCopyCharactersREP adds too much // additional setup and checking in GenerateCopyCharactersREP adds too much
// overhead. Copying of overlapping regions is not supported. // overhead. Copying of overlapping regions is not supported.
static void GenerateCopyCharacters(MacroAssembler* masm, static void GenerateCopyCharacters(MacroAssembler* masm,
Register dest, Register dest,
Register src, Register src,
Register count, Register count,
bool ascii); bool ascii);
// Generate code for copying characters using the rep movs instruction. // Generate code for copying characters using the rep movs instruction.
// Copies rcx characters from rsi to rdi. Copying of overlapping regions is // Copies rcx characters from rsi to rdi. Copying of overlapping regions is
// not supported. // not supported.
static void GenerateCopyCharactersREP(MacroAssembler* masm, static void GenerateCopyCharactersREP(MacroAssembler* masm,
Register dest, // Must be rdi. Register dest, // Must be rdi.
Register src, // Must be rsi. Register src, // Must be rsi.
Register count, // Must be rcx. Register count, // Must be rcx.
bool ascii); bool ascii);
// Probe the symbol table for a two character string. If the string is // Probe the symbol table for a two character string. If the string is
...@@ -893,26 +893,27 @@ class StringHelper : public AllStatic { ...@@ -893,26 +893,27 @@ class StringHelper : public AllStatic {
// does not guarantee that the string is not in the symbol table. If the // does not guarantee that the string is not in the symbol table. If the
// string is found the code falls through with the string in register rax. // string is found the code falls through with the string in register rax.
static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
Register c1, Register c1,
Register c2, Register c2,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Register scratch3, Register scratch3,
Register scratch4, Register scratch4,
Label* not_found); Label* not_found);
// Generate string hash. // Generate string hash.
static void GenerateHashInit(MacroAssembler* masm, static void GenerateHashInit(MacroAssembler* masm,
Register hash, Register hash,
Register character, Register character,
Register scratch); Register scratch);
static void GenerateHashAddCharacter(MacroAssembler* masm, static void GenerateHashAddCharacter(MacroAssembler* masm,
Register hash, Register hash,
Register character, Register character,
Register scratch); Register scratch);
static void GenerateHashGetHash(MacroAssembler* masm, static void GenerateHashGetHash(MacroAssembler* masm,
Register hash, Register hash,
Register scratch); Register scratch);
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment