[turbofan] Remove the no-context hack for JSToNumber.

The ToNumberStub is now able to handle all plain primitives (Numbers,
Booleans, Null, Undefined and Strings) without context access.

TEST=cctest,mjsunit,unittests

Review URL: https://codereview.chromium.org/801333002

Cr-Commit-Position: refs/heads/master@{#25814}
This commit is contained in:
bmeurer 2014-12-15 03:14:03 -08:00 committed by Commit bot
parent 3c30f6e1f6
commit d211608a3e
6 changed files with 134 additions and 35 deletions

View File

@ -3181,18 +3181,43 @@ void SubStringStub::Generate(MacroAssembler* masm) {
void ToNumberStub::Generate(MacroAssembler* masm) {
// The ToNumber stub takes one argument in r0.
Label check_heap_number, call_builtin;
__ JumpIfNotSmi(r0, &check_heap_number);
Label not_smi;
__ JumpIfNotSmi(r0, &not_smi);
__ Ret();
__ bind(&not_smi);
__ bind(&check_heap_number);
Label not_heap_number;
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
__ CompareRoot(r1, Heap::kHeapNumberMapRootIndex);
__ b(ne, &call_builtin);
__ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
// r0: object
// r1: instance type.
__ cmp(r1, Operand(HEAP_NUMBER_TYPE));
__ b(ne, &not_heap_number);
__ Ret();
__ bind(&not_heap_number);
__ bind(&call_builtin);
__ push(r0);
Label not_string, slow_string;
__ cmp(r1, Operand(FIRST_NONSTRING_TYPE));
__ b(hs, &not_string);
// Check if string has a cached array index.
__ ldr(r2, FieldMemOperand(r0, String::kHashFieldOffset));
__ tst(r2, Operand(String::kContainsCachedArrayIndexMask));
__ b(ne, &slow_string);
__ IndexFromHash(r2, r0);
__ Ret();
__ bind(&slow_string);
__ push(r0); // Push argument.
__ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
__ bind(&not_string);
Label not_oddball;
__ cmp(r1, Operand(ODDBALL_TYPE));
__ b(ne, &not_oddball);
__ ldr(r0, FieldMemOperand(r0, Oddball::kToNumberOffset));
__ Ret();
__ bind(&not_oddball);
__ push(r0); // Push argument.
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
}

View File

@ -3887,16 +3887,43 @@ void SubStringStub::Generate(MacroAssembler* masm) {
void ToNumberStub::Generate(MacroAssembler* masm) {
// The ToNumber stub takes one argument in x0.
Label check_heap_number, call_builtin;
__ JumpIfNotSmi(x0, &check_heap_number);
Label not_smi;
__ JumpIfNotSmi(x0, &not_smi);
__ Ret();
__ Bind(&not_smi);
__ bind(&check_heap_number);
__ JumpIfNotHeapNumber(x0, &call_builtin);
Label not_heap_number;
__ Ldr(x1, FieldMemOperand(x0, HeapObject::kMapOffset));
__ Ldrb(x1, FieldMemOperand(x1, Map::kInstanceTypeOffset));
// x0: object
// x1: instance type
__ Cmp(x1, HEAP_NUMBER_TYPE);
__ B(ne, &not_heap_number);
__ Ret();
__ Bind(&not_heap_number);
__ bind(&call_builtin);
__ push(x0);
Label not_string, slow_string;
__ Cmp(x1, FIRST_NONSTRING_TYPE);
__ B(hs, &not_string);
// Check if string has a cached array index.
__ Ldr(x2, FieldMemOperand(x0, String::kHashFieldOffset));
__ Tst(x2, Operand(String::kContainsCachedArrayIndexMask));
__ B(ne, &slow_string);
__ IndexFromHash(x2, x0);
__ Ret();
__ Bind(&slow_string);
__ Push(x0); // Push argument.
__ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
__ Bind(&not_string);
Label not_oddball;
__ Cmp(x1, ODDBALL_TYPE);
__ B(ne, &not_oddball);
__ Ldr(x0, FieldMemOperand(x0, Oddball::kToNumberOffset));
__ Ret();
__ Bind(&not_oddball);
__ Push(x0); // Push argument.
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
}

View File

@ -232,12 +232,6 @@ void JSGenericLowering::LowerJSToBoolean(Node* node) {
void JSGenericLowering::LowerJSToNumber(Node* node) {
Callable callable = CodeFactory::ToNumber(isolate());
// TODO(mstarzinger): Embedding the context this way prevents sharing of code
// across native contexts.
if (!info_context_constant_.is_set()) {
info_context_constant_.set(jsgraph()->HeapConstant(info()->context()));
}
node->ReplaceInput(1, info_context_constant_.get());
ReplaceWithStubCall(node, callable, FlagsForNode(node));
}

View File

@ -60,7 +60,6 @@ class JSGenericLowering : public Reducer {
private:
CompilationInfo* info_;
SetOncePointer<Node> info_context_constant_;
JSGraph* jsgraph_;
Linkage* linkage_;
};

View File

@ -3227,18 +3227,45 @@ void SubStringStub::Generate(MacroAssembler* masm) {
void ToNumberStub::Generate(MacroAssembler* masm) {
// The ToNumber stub takes one argument in eax.
Label check_heap_number, call_builtin;
__ JumpIfNotSmi(eax, &check_heap_number, Label::kNear);
Label not_smi;
__ JumpIfNotSmi(eax, &not_smi, Label::kNear);
__ Ret();
__ bind(&not_smi);
__ bind(&check_heap_number);
Label not_heap_number;
__ CompareMap(eax, masm->isolate()->factory()->heap_number_map());
__ j(not_equal, &call_builtin, Label::kNear);
__ j(not_equal, &not_heap_number, Label::kNear);
__ Ret();
__ bind(&not_heap_number);
__ bind(&call_builtin);
__ pop(ecx); // Pop return address.
__ push(eax);
Label not_string, slow_string;
__ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi);
// eax: object
// edi: object map
__ j(above_equal, &not_string, Label::kNear);
// Check if string has a cached array index.
__ test(FieldOperand(eax, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask));
__ j(not_zero, &slow_string, Label::kNear);
__ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
__ IndexFromHash(eax, eax);
__ Ret();
__ bind(&slow_string);
__ pop(ecx); // Pop return address.
__ push(eax); // Push argument.
__ push(ecx); // Push return address.
__ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
__ bind(&not_string);
Label not_oddball;
__ CmpInstanceType(edi, ODDBALL_TYPE);
__ j(not_equal, &not_oddball, Label::kNear);
__ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
__ Ret();
__ bind(&not_oddball);
__ pop(ecx); // Pop return address.
__ push(eax); // Push argument.
__ push(ecx); // Push return address.
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
}

View File

@ -3169,20 +3169,47 @@ void SubStringStub::Generate(MacroAssembler* masm) {
void ToNumberStub::Generate(MacroAssembler* masm) {
// The ToNumber stub takes one argument in rax.
Label check_heap_number, call_builtin;
__ JumpIfNotSmi(rax, &check_heap_number, Label::kNear);
Label not_smi;
__ JumpIfNotSmi(rax, &not_smi, Label::kNear);
__ Ret();
__ bind(&not_smi);
__ bind(&check_heap_number);
Label not_heap_number;
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &call_builtin, Label::kNear);
__ j(not_equal, &not_heap_number, Label::kNear);
__ Ret();
__ bind(&not_heap_number);
__ bind(&call_builtin);
__ popq(rcx); // Pop return address.
__ pushq(rax);
__ pushq(rcx); // Push return address.
Label not_string, slow_string;
__ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdi);
// rax: object
// rdi: object map
__ j(above_equal, &not_string, Label::kNear);
// Check if string has a cached array index.
__ testl(FieldOperand(rax, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask));
__ j(not_zero, &slow_string, Label::kNear);
__ movl(rax, FieldOperand(rax, String::kHashFieldOffset));
__ IndexFromHash(rax, rax);
__ Ret();
__ bind(&slow_string);
__ PopReturnAddressTo(rcx); // Pop return address.
__ Push(rax); // Push argument.
__ PushReturnAddressFrom(rcx); // Push return address.
__ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
__ bind(&not_string);
Label not_oddball;
__ CmpInstanceType(rdi, ODDBALL_TYPE);
__ j(not_equal, &not_oddball, Label::kNear);
__ movp(rax, FieldOperand(rax, Oddball::kToNumberOffset));
__ Ret();
__ bind(&not_oddball);
__ PopReturnAddressTo(rcx); // Pop return address.
__ Push(rax); // Push argument.
__ PushReturnAddressFrom(rcx); // Push return address.
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
}