MIPS: Move Maps' back pointers from "transitions" to "constructor" field
authorakos.palfi <akos.palfi@imgtec.com>
Wed, 25 Feb 2015 03:24:48 +0000 (19:24 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 25 Feb 2015 03:25:02 +0000 (03:25 +0000)
Port affcfaf42801414d25b3e57271a9803a026f40ed

BUG=

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

Cr-Commit-Position: refs/heads/master@{#26837}

src/mips/full-codegen-mips.cc
src/mips/lithium-codegen-mips.cc
src/mips/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h
src/mips64/full-codegen-mips64.cc
src/mips64/lithium-codegen-mips64.cc
src/mips64/macro-assembler-mips64.cc
src/mips64/macro-assembler-mips64.h

index c5749fcf3a6d472e83df5dc93e5403223c824698..91753162faf4e1ecc7d30af4f0e8ae583eda6091 100644 (file)
@@ -3757,9 +3757,10 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
 
   // Check if the constructor in the map is a JS function.
-  __ lw(v0, FieldMemOperand(v0, Map::kConstructorOffset));
-  __ GetObjectType(v0, a1, a1);
-  __ Branch(&non_function_constructor, ne, a1, Operand(JS_FUNCTION_TYPE));
+  Register instance_type = a2;
+  __ GetMapConstructor(v0, v0, a1, instance_type);
+  __ Branch(&non_function_constructor, ne, instance_type,
+            Operand(JS_FUNCTION_TYPE));
 
   // v0 now contains the constructor function. Grab the
   // instance class name from there.
index 0244e7ee0d5a3391a50948ec1668f628ee844eed..3be283de831ad40240e83daafb6c1cf5044f8cc9 100644 (file)
@@ -2657,14 +2657,16 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
 
   // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
   // Check if the constructor in the map is a function.
-  __ lw(temp, FieldMemOperand(temp, Map::kConstructorOffset));
+  Register instance_type = scratch1();
+  DCHECK(!instance_type.is(temp));
+  DCHECK(!instance_type.is(temp2));
+  __ GetMapConstructor(temp, temp, temp2, instance_type);
 
   // Objects with a non-function constructor have class 'Object'.
-  __ GetObjectType(temp, temp2, temp2);
   if (String::Equals(class_name, isolate()->factory()->Object_string())) {
-    __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE));
+    __ Branch(is_true, ne, instance_type, Operand(JS_FUNCTION_TYPE));
   } else {
-    __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE));
+    __ Branch(is_false, ne, instance_type, Operand(JS_FUNCTION_TYPE));
   }
 
   // temp now contains the constructor function. Grab the
index 972530ee355974af4d593e50d1a26b77dd5d5deb..de3c08afff060855886bbdf8490e51fb1fad6b59 100644 (file)
@@ -4321,6 +4321,20 @@ void MacroAssembler::IsObjectNameType(Register object,
 // Support functions.
 
 
+void MacroAssembler::GetMapConstructor(Register result, Register map,
+                                       Register temp, Register temp2) {
+  Label done, loop;
+  lw(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
+  bind(&loop);
+  JumpIfSmi(result, &done);
+  GetObjectType(result, temp, temp2);
+  Branch(&done, ne, temp2, Operand(MAP_TYPE));
+  lw(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
+  Branch(&loop);
+  bind(&done);
+}
+
+
 void MacroAssembler::TryGetFunctionPrototype(Register function,
                                              Register result,
                                              Register scratch,
@@ -4373,7 +4387,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
     // Non-instance prototype: Fetch prototype from constructor field
     // in initial map.
     bind(&non_instance);
-    lw(result, FieldMemOperand(result, Map::kConstructorOffset));
+    GetMapConstructor(result, result, scratch, at);
   }
 
   // All done.
index 02845e2bbd9be0ecf82ab4265c9581aa8302a446..1bce7786c5471942cead7041476e81d0e99251e8 100644 (file)
@@ -998,6 +998,11 @@ class MacroAssembler: public Assembler {
   // -------------------------------------------------------------------------
   // Support functions.
 
+  // Machine code version of Map::GetConstructor().
+  // |temp| holds |result|'s map when done, and |temp2| its instance type.
+  void GetMapConstructor(Register result, Register map, Register temp,
+                         Register temp2);
+
   // Try to get function prototype of a function and puts the value in
   // the result register. Checks that the function really is a
   // function and jumps to the miss label if the fast checks fail. The
index 5fe0c5a6ee9f8e349761b3b0a9e5c2e78a8d6ef8..9809514d1477c83865c086c3e32aa03dba60ec93 100644 (file)
@@ -3758,9 +3758,10 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
 
   // Check if the constructor in the map is a JS function.
-  __ ld(v0, FieldMemOperand(v0, Map::kConstructorOffset));
-  __ GetObjectType(v0, a1, a1);
-  __ Branch(&non_function_constructor, ne, a1, Operand(JS_FUNCTION_TYPE));
+  Register instance_type = a2;
+  __ GetMapConstructor(v0, v0, a1, instance_type);
+  __ Branch(&non_function_constructor, ne, instance_type,
+            Operand(JS_FUNCTION_TYPE));
 
   // v0 now contains the constructor function. Grab the
   // instance class name from there.
index 8e5278499efe5c9797dc93a56637cb6bf34c1401..bb256bff3cf89cb0bdfa30fc6583438eb2a60ec8 100644 (file)
@@ -2618,14 +2618,16 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
 
   // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
   // Check if the constructor in the map is a function.
-  __ ld(temp, FieldMemOperand(temp, Map::kConstructorOffset));
+  Register instance_type = scratch1();
+  DCHECK(!instance_type.is(temp));
+  DCHECK(!instance_type.is(temp2));
+  __ GetMapConstructor(temp, temp, temp2, instance_type);
 
   // Objects with a non-function constructor have class 'Object'.
-  __ GetObjectType(temp, temp2, temp2);
   if (String::Equals(class_name, isolate()->factory()->Object_string())) {
-    __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE));
+    __ Branch(is_true, ne, instance_type, Operand(JS_FUNCTION_TYPE));
   } else {
-    __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE));
+    __ Branch(is_false, ne, instance_type, Operand(JS_FUNCTION_TYPE));
   }
 
   // temp now contains the constructor function. Grab the
index 64b3d552e3167def47cb2772a4e1cf03041bd8e7..bc935326cfe1aac1e816742154a45e0bcc0aeca6 100644 (file)
@@ -4243,6 +4243,20 @@ void MacroAssembler::IsObjectNameType(Register object,
 // Support functions.
 
 
+void MacroAssembler::GetMapConstructor(Register result, Register map,
+                                       Register temp, Register temp2) {
+  Label done, loop;
+  ld(result, FieldMemOperand(map, Map::kConstructorOrBackPointerOffset));
+  bind(&loop);
+  JumpIfSmi(result, &done);
+  GetObjectType(result, temp, temp2);
+  Branch(&done, ne, temp2, Operand(MAP_TYPE));
+  ld(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
+  Branch(&loop);
+  bind(&done);
+}
+
+
 void MacroAssembler::TryGetFunctionPrototype(Register function,
                                              Register result,
                                              Register scratch,
@@ -4295,7 +4309,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
     // Non-instance prototype: Fetch prototype from constructor field
     // in initial map.
     bind(&non_instance);
-    ld(result, FieldMemOperand(result, Map::kConstructorOffset));
+    GetMapConstructor(result, result, scratch, at);
   }
 
   // All done.
index d38982f6547d1ca05e1a6c2650fec314e1d373ed..52db677d5d961f04eac5c5fb5423ca1a724b8cf1 100644 (file)
@@ -1028,6 +1028,11 @@ class MacroAssembler: public Assembler {
   // -------------------------------------------------------------------------
   // Support functions.
 
+  // Machine code version of Map::GetConstructor().
+  // |temp| holds |result|'s map when done, and |temp2| its instance type.
+  void GetMapConstructor(Register result, Register map, Register temp,
+                         Register temp2);
+
   // Try to get function prototype of a function and puts the value in
   // the result register. Checks that the function really is a
   // function and jumps to the miss label if the fast checks fail. The