Revision: 21470
Author:   plin...@gmail.com
Date:     Fri May 23 18:05:40 2014 UTC
Log: 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=
R=plin...@gmail.com

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

Patch from Balazs Kilvady <kilva...@homejinni.com>.
http://code.google.com/p/v8/source/detail?r=21470

Modified:
 /branches/bleeding_edge/src/mips/builtins-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.h

=======================================
--- /branches/bleeding_edge/src/mips/builtins-mips.cc Tue May 6 19:24:11 2014 UTC +++ /branches/bleeding_edge/src/mips/builtins-mips.cc Fri May 23 18:05:40 2014 UTC
@@ -319,7 +319,6 @@

 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 @@
   //  -- 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 -------------
@@ -360,9 +353,6 @@
     __ sll(a0, a0, kSmiTagSize);  // Tag arguments count.
     __ MultiPushReversed(a0.bit() | a1.bit());

-    // Use t7 to hold undefined, which is used in several places below.
-    __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
-
     Label rt_call, allocated;
// Try to allocate the object without transitioning into C code. If any of // the preconditions is not met, the code bails out to the runtime call.
@@ -389,19 +379,23 @@
       __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
       __ Branch(&rt_call, eq, a3, Operand(JS_FUNCTION_TYPE));

-      if (count_constructions) {
+      // Use t7 to hold undefined, which is used in several places below.
+      __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
+
+      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>(t2, t0);
+ __ Branch(&allocate, eq, t2, 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));
+        __ Branch(USE_DELAY_SLOT,
+            &allocate, ne, t2, Operand(JSFunction::kFinishSlackTracking));
+        __ sw(t0, bit_field3);  // In delay slot.

         __ 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);
@@ -441,29 +435,39 @@
       // a3: object size (in words, including memento if create_memento)
       // t4: JSObject (not tagged)
       // t5: First in-object property of JSObject (not tagged)
+      // t2: slack tracking counter (non-API function case)
       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.
+        __ Branch(&no_inobject_slack_tracking,
+            eq, t2, Operand(JSFunction::kNoSlackTracking));
+
+        // Allocate object with a slack.
__ lbu(a0, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset));
         __ sll(at, a0, kPointerSizeLog2);
         __ addu(a0, t5, at);
-        __ sll(at, a3, kPointerSizeLog2);
-        __ Addu(t6, t4, Operand(at));   // End of object.
         // a0: offset of first field after pre-allocated fields
         if (FLAG_debug_code) {
+          __ sll(at, a3, kPointerSizeLog2);
+          __ Addu(t6, t4, Operand(at));   // End of object.
           __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields,
               a0, Operand(t6));
         }
         __ 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 @@
         __ 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,11 +551,11 @@
       __ 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);
-          __ Assert(eq, kUndefinedValueNotLoaded, t7, Operand(t8));
+          __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
+          __ Assert(eq, kUndefinedValueNotLoaded, t7, Operand(t2));
         }
         __ jmp(&entry);
         __ bind(&loop);
@@ -676,7 +679,7 @@
     }

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

@@ -723,20 +726,15 @@
__ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
   __ Ret();
 }
-
-
-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);
 }


=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.h Thu May 15 12:10:00 2014 UTC +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.h Fri May 23 18:05:40 2014 UTC
@@ -1484,11 +1484,19 @@
   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