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,14 +665,46 @@ class GenericBinaryOpStub : public CodeStub { ...@@ -665,14 +665,46 @@ 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,
...@@ -683,7 +715,7 @@ class StringStubBase: public CodeStub { ...@@ -683,7 +715,7 @@ class StringStubBase: public CodeStub {
// 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,
...@@ -702,7 +734,7 @@ class StringStubBase: public CodeStub { ...@@ -702,7 +734,7 @@ 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,
...@@ -713,16 +745,19 @@ class StringStubBase: public CodeStub { ...@@ -713,16 +745,19 @@ class StringStubBase: public CodeStub {
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);
void GenerateHashAddCharacter(MacroAssembler* masm, static void GenerateHashAddCharacter(MacroAssembler* masm,
Register hash, Register hash,
Register character); Register character);
void GenerateHashGetHash(MacroAssembler* masm, static void GenerateHashGetHash(MacroAssembler* masm,
Register hash); Register hash);
private:
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 - - -
------------------------------------- -------------------------------------
......
...@@ -913,6 +913,7 @@ class StringHelper : public AllStatic { ...@@ -913,6 +913,7 @@ class StringHelper : public AllStatic {
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