Port
09de997b3504368d40644afa7310b90faff5d09c
Original commit message:
This adds a new ToString runtime function and a fast-path ToStringStub
(which is just a simple dispatcher for existing functionality), and also
implements %_ToName using the ToStringStub.
R=bmeurer@chromium.org, jyan@ca.ibm.com, dstence@us.ibm.com, joransiu@ca.ibm.com
BUG=v8:4307
LOG=n
Review URL: https://codereview.chromium.org/
1310493004
Cr-Commit-Position: refs/heads/master@{#30449}
}
+void FullCodeGenerator::EmitToString(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into r3 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ ToStringStub stub(isolate());
+ __ CallStub(&stub);
+ context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitToName(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ // Load the argument into r3 and convert it.
+ VisitForAccumulatorValue(args->at(0));
+
+ Label convert, done_convert;
+ __ JumpIfSmi(r3, &convert);
+ STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
+ __ CompareObjectType(r3, r4, r4, LAST_NAME_TYPE);
+ __ ble(&done_convert);
+ __ bind(&convert);
+ ToStringStub stub(isolate());
+ __ CallStub(&stub);
+ __ bind(&done_convert);
+ context()->Plug(r3);
+}
+
+
void FullCodeGenerator::EmitToObject(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_EQ(1, args->length());
__ IncrementCounter(counters->string_ctor_conversions(), 1, r6, r7);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
- __ push(r3);
- __ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION);
+ ToStringStub stub(masm->isolate());
+ __ CallStub(&stub);
}
__ pop(function);
__ mr(argument, r3);
__ blr();
__ bind(¬_smi);
- Label not_heap_number;
- __ LoadP(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
- __ lbz(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
- // r3: object
- // r4: instance type.
- __ cmpi(r4, Operand(HEAP_NUMBER_TYPE));
- __ bne(¬_heap_number);
- __ blr();
- __ bind(¬_heap_number);
+ __ CompareObjectType(r3, r4, r4, HEAP_NUMBER_TYPE);
+ // r3: receiver
+ // r4: receiver instance type
+ __ Ret(eq);
Label not_string, slow_string;
__ cmpli(r4, Operand(FIRST_NONSTRING_TYPE));
}
+void ToStringStub::Generate(MacroAssembler* masm) {
+ // The ToString stub takes one argument in r3.
+ Label is_number;
+ __ JumpIfSmi(r3, &is_number);
+
+ __ CompareObjectType(r3, r4, r4, FIRST_NONSTRING_TYPE);
+ // r3: receiver
+ // r4: receiver instance type
+ __ Ret(lt);
+
+ Label not_heap_number;
+ __ cmpi(r4, Operand(HEAP_NUMBER_TYPE));
+ __ bne(¬_heap_number);
+ __ bind(&is_number);
+ NumberToStringStub stub(isolate());
+ __ TailCallStub(&stub);
+ __ bind(¬_heap_number);
+
+ Label not_oddball;
+ __ cmpi(r4, Operand(ODDBALL_TYPE));
+ __ bne(¬_oddball);
+ __ LoadP(r3, FieldMemOperand(r3, Oddball::kToStringOffset));
+ __ Ret();
+ __ bind(¬_oddball);
+
+ __ push(r3); // Push argument.
+ __ TailCallRuntime(Runtime::kToString, 1, 1);
+}
+
+
void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left,
Register right,
}
+// static
+const Register ToStringDescriptor::ReceiverRegister() { return r3; }
+
+
// static
const Register ToObjectDescriptor::ReceiverRegister() { return r3; }
void BranchOnNoOverflow(Label* label) { bge(label, cr0); }
- void RetOnOverflow(void) {
- Label label;
+ void RetOnOverflow(void) { Ret(lt, cr0); }
- blt(&label, cr0);
- Ret();
- bind(&label);
- }
-
- void RetOnNoOverflow(void) {
- Label label;
-
- bge(&label, cr0);
- Ret();
- bind(&label);
- }
+ void RetOnNoOverflow(void) { Ret(ge, cr0); }
// ---------------------------------------------------------------------------
// Runtime calls