[turbofan] Remove the no-context hack for JSToNumber.
authorbmeurer <bmeurer@chromium.org>
Mon, 15 Dec 2014 11:14:03 +0000 (03:14 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 15 Dec 2014 11:14:16 +0000 (11:14 +0000)
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}

src/arm/code-stubs-arm.cc
src/arm64/code-stubs-arm64.cc
src/compiler/js-generic-lowering.cc
src/compiler/js-generic-lowering.h
src/ia32/code-stubs-ia32.cc
src/x64/code-stubs-x64.cc

index 47df2a353e989c6f824bf69199d3c58f6bd0c62c..ef286bbe01585a7a1ad56d3e71c0b5fdc278233f 100644 (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);
+
+  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);
 
-  __ bind(&call_builtin);
-  __ push(r0);
+  __ push(r0);  // Push argument.
   __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
 }
 
index 6392640741ba3513f025927b0365e5abd0d50bfe..e773b531a1e2784ca34a05626728621c5fd4adc2 100644 (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(&check_heap_number);
-  __ JumpIfNotHeapNumber(x0, &call_builtin);
+  __ Bind(&not_smi);
+
+  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);
+
+  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);
 
-  __ bind(&call_builtin);
-  __ push(x0);
+  __ Push(x0);  // Push argument.
   __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
 }
 
index 3275256a2811b24743fb89de19a1889aeba470b5..48864423146007ec632915d4ac1ad0658ca80c93 100644 (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));
 }
 
index c3049883cd67be9cf50b12669e91135657b28734..eb234b84ff3a94fa27b5aa4c4b9255cd4ed3bc27 100644 (file)
@@ -60,7 +60,6 @@ class JSGenericLowering : public Reducer {
 
  private:
   CompilationInfo* info_;
-  SetOncePointer<Node> info_context_constant_;
   JSGraph* jsgraph_;
   Linkage* linkage_;
 };
index 8db05a16e8b9b1a9536a96fdde136477894fe59e..b75ae3a53100cb077dc6897355045ea84b9b91c7 100644 (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);
+
+  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);
 
-  __ bind(&call_builtin);
-  __ pop(ecx);  // Pop return address.
-  __ push(eax);
+  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);
 }
index da72c29f3b434a817f80efe650a727fe71cb3183..f327b5008543bdfa4f541badfc04e0ababdf4f26 100644 (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);
+
+  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);
 
-  __ bind(&call_builtin);
-  __ popq(rcx);  // Pop return address.
-  __ pushq(rax);
-  __ pushq(rcx);  // Push return address.
+  __ PopReturnAddressTo(rcx);     // Pop return address.
+  __ Push(rax);                   // Push argument.
+  __ PushReturnAddressFrom(rcx);  // Push return address.
   __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
 }