Reviewers: danno, Igor Sheludko, Paul Lind, kisg, palfia, dusmil,

Description:
MIPS: Reland r21442 "Inobject slack tracking is done on a per-closure basis
instead of per-shared info basis."

Port r21457 (8db39a8)

Original commit message:
This fixes inobject slack tracking for prototype inheritance pattern that uses
closures.

BUG=

Please review this at https://codereview.chromium.org/294973013/

SVN Base: https://github.com/v8/v8.git@gbl

Affected files (+43, -37 lines):
  M src/mips/builtins-mips.cc
  M src/mips/macro-assembler-mips.h


Index: src/mips/builtins-mips.cc
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index fdd062b6b69cb53e3ee1e527088ddf435030c647..abf78b3d35c1be4c0e6b8ef2f0c946a6329b14f2 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -319,7 +319,6 @@ void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {

 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
                                            bool is_api_function,
-                                           bool count_constructions,
                                            bool create_memento) {
   // ----------- S t a t e -------------
   //  -- a0     : number of arguments
@@ -329,15 +328,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   //  -- sp[...]: constructor arguments
   // -----------------------------------

-  // Should never count constructions for api objects.
-  ASSERT(!is_api_function || !count_constructions);
-
   // Should never create mementos for api functions.
   ASSERT(!is_api_function || !create_memento);

-  // Should never create mementos before slack tracking is finished.
-  ASSERT(!count_constructions || !create_memento);
-
   Isolate* isolate = masm->isolate();

   // ----------- S t a t e -------------
@@ -389,19 +382,19 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
       __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
       __ Branch(&rt_call, eq, a3, Operand(JS_FUNCTION_TYPE));

-      if (count_constructions) {
+      if (!is_api_function) {
         Label allocate;
+        MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset);
+        // Check if slack tracking is enabled.
+        __ lw(t0, bit_field3);
+        __ DecodeField<Map::ConstructionCount>(a3, t0);
+ __ Branch(&allocate, eq, a3, Operand(JSFunction::kNoSlackTracking));
         // Decrease generous allocation count.
- __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
-        MemOperand constructor_count =
- FieldMemOperand(a3, SharedFunctionInfo::kConstructionCountOffset);
-        __ lbu(t0, constructor_count);
-        __ Subu(t0, t0, Operand(1));
-        __ sb(t0, constructor_count);
-        __ Branch(&allocate, ne, t0, Operand(zero_reg));
+        __ Subu(t0, t0, Operand(1 << Map::ConstructionCount::kShift));
+        __ sw(t0, bit_field3);
+ __ Branch(&allocate, ne, a3, Operand(JSFunction::kFinishSlackTracking));

         __ Push(a1, a2, a1);  // a1 = Constructor.
- // The call will replace the stub, so the countdown is only done once.
         __ CallRuntime(Runtime::kHiddenFinalizeInstanceSize, 1);

         __ Pop(a1, a2);
@@ -443,8 +436,16 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
       // t5: First in-object property of JSObject (not tagged)
       ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);

-      if (count_constructions) {
-        __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
+      if (!is_api_function) {
+        Label no_inobject_slack_tracking;
+
+        // Check if slack tracking is enabled.
+        __ lw(t0, FieldMemOperand(a2, Map::kBitField3Offset));
+        __ DecodeField<Map::ConstructionCount>(t0);
+        __ Branch(&no_inobject_slack_tracking,
+            eq, t0, Operand(JSFunction::kNoSlackTracking));
+
+        // Allocate object with a slack.
__ lbu(a0, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset));
         __ sll(at, a0, kPointerSizeLog2);
         __ addu(a0, t5, at);
@@ -458,12 +459,15 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ InitializeFieldsWithFiller(t5, a0, t7);
         // To allow for truncation.
         __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex);
-        __ InitializeFieldsWithFiller(t5, t6, t7);
-      } else if (create_memento) {
-        __ Subu(t7, a3, Operand(AllocationMemento::kSize / kPointerSize));
-        __ sll(at, t7, kPointerSizeLog2);
-        __ Addu(a0, t4, Operand(at));  // End of object.
-        __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
+        // Fill the remaining fields with one pointer filler map.
+
+        __ bind(&no_inobject_slack_tracking);
+      }
+
+      if (create_memento) {
+        __ Subu(a0, a3, Operand(AllocationMemento::kSize / kPointerSize));
+        __ sll(a0, a0, kPointerSizeLog2);
+        __ Addu(a0, t4, Operand(a0));  // End of object.
         __ InitializeFieldsWithFiller(t5, a0, t7);

         // Fill in memento fields.
@@ -478,7 +482,6 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ sw(t7, MemOperand(t5));
         __ Addu(t5, t5, kPointerSize);
       } else {
-        __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
         __ sll(at, a3, kPointerSizeLog2);
         __ Addu(a0, t4, Operand(at));  // End of object.
         __ InitializeFieldsWithFiller(t5, a0, t7);
@@ -548,7 +551,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
       __ addu(t6, a2, t3);  // End of object.
       ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
       { Label loop, entry;
-        if (count_constructions) {
+        if (!is_api_function || create_memento) {
           __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
         } else if (FLAG_debug_code) {
           __ LoadRoot(t8, Heap::kUndefinedValueRootIndex);
@@ -676,7 +679,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
     }

     // Store offset of return address for deoptimizer.
-    if (!is_api_function && !count_constructions) {
+    if (!is_api_function) {
masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
     }

@@ -725,18 +728,13 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 }


-void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
-  Generate_JSConstructStubHelper(masm, false, true, false);
-}
-
-
 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
- Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
+  Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
 }


 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
-  Generate_JSConstructStubHelper(masm, true, false, false);
+  Generate_JSConstructStubHelper(masm, true, false);
 }


Index: src/mips/macro-assembler-mips.h
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h index 1f815d91c05d04652265ef789ccdedbe858170eb..a979475ce7d27ac6dd62233f10e91f5c0aa725b3 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1484,11 +1484,19 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
   void NumberOfOwnDescriptors(Register dst, Register map);

   template<typename Field>
-  void DecodeField(Register reg) {
+  void DecodeField(Register dst, Register src) {
     static const int shift = Field::kShift;
     static const int mask = Field::kMask >> shift;
-    srl(reg, reg, shift);
-    And(reg, reg, Operand(mask));
+    static const int size = Field::kSize;
+    srl(dst, src, shift);
+    if (shift + size != 32) {
+      And(dst, dst, Operand(mask));
+    }
+  }
+
+  template<typename Field>
+  void DecodeField(Register reg) {
+    DecodeField<Field>(reg, reg);
   }

   // Generates function and stub prologue code.


--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to