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.