Symbols for type cells. We can make more efficient code to check against type cells...
authormvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Mar 2014 09:10:18 +0000 (09:10 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Mar 2014 09:10:18 +0000 (09:10 +0000)
BUG=
R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19706 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

19 files changed:
include/v8.h
src/a64/builtins-a64.cc
src/a64/code-stubs-a64.cc
src/a64/lithium-codegen-a64.cc
src/arm/builtins-arm.cc
src/arm/code-stubs-arm.cc
src/arm/lithium-codegen-arm.cc
src/full-codegen.cc
src/heap.cc
src/heap.h
src/ia32/builtins-ia32.cc
src/ia32/code-stubs-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/objects-inl.h
src/runtime.cc
src/x64/builtins-x64.cc
src/x64/code-stubs-x64.cc
src/x64/lithium-codegen-x64.cc
test/cctest/test-heap.cc

index 3d9311f..cfffc91 100644 (file)
@@ -5395,7 +5395,7 @@ class Internals {
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 142;
+  static const int kEmptyStringRootIndex = 144;
 
   static const int kNodeClassIdOffset = 1 * kApiPointerSize;
   static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
index 797fbc3..be70009 100644 (file)
@@ -149,10 +149,9 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
   }
 
   // Run the native code for the Array function called as a normal function.
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
-  __ Mov(x2, Operand(undefined_sentinel));
+  Handle<Object> megamorphic_sentinel =
+      TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+  __ Mov(x2, Operand(megamorphic_sentinel));
   ArrayConstructorStub stub(masm->isolate());
   __ TailCallStub(&stub);
 }
@@ -715,9 +714,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
     __ Mov(x0, argc);
     if (is_construct) {
       // No type feedback cell is available.
-      Handle<Object> undefined_sentinel(
-          masm->isolate()->heap()->undefined_value(), masm->isolate());
-      __ Mov(x2, Operand(undefined_sentinel));
+      Handle<Object> megamorphic_sentinel =
+          TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+      __ Mov(x2, Operand(megamorphic_sentinel));
 
       CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
       __ CallStub(&stub);
index 6e246b7..a3aad78 100644 (file)
@@ -3276,9 +3276,9 @@ static void GenerateRecordCallTarget(MacroAssembler* masm,
   Label initialize, done, miss, megamorphic, not_array_function;
 
   ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
-            masm->isolate()->heap()->undefined_value());
+            masm->isolate()->heap()->megamorphic_symbol());
   ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
-            masm->isolate()->heap()->the_hole_value());
+            masm->isolate()->heap()->uninitialized_symbol());
 
   // Load the cache state.
   __ Add(scratch1, feedback_vector,
@@ -3307,13 +3307,13 @@ static void GenerateRecordCallTarget(MacroAssembler* masm,
 
   // A monomorphic miss (i.e, here the cache is not uninitialized) goes
   // megamorphic.
-  __ JumpIfRoot(scratch1, Heap::kTheHoleValueRootIndex, &initialize);
+  __ JumpIfRoot(scratch1, Heap::kUninitializedSymbolRootIndex, &initialize);
   // MegamorphicSentinel is an immortal immovable object (undefined) so no
   // write-barrier is needed.
   __ Bind(&megamorphic);
   __ Add(scratch1, feedback_vector,
          Operand::UntagSmiAndScale(index, kPointerSizeLog2));
-  __ LoadRoot(scratch2, Heap::kUndefinedValueRootIndex);
+  __ LoadRoot(scratch2, Heap::kMegamorphicSymbolRootIndex);
   __ Str(scratch2, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
   __ B(&done);
 
@@ -3366,7 +3366,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
   ASM_LOCATION("CallFunctionStub::Generate");
   // x1  function    the function to call
   // x2 : feedback vector
-  // x3 : slot in feedback vector (smi) (if x2 is not undefined)
+  // x3 : slot in feedback vector (smi) (if x2 is not the megamorphic symbol)
   Register function = x1;
   Register cache_cell = x2;
   Register slot = x3;
@@ -3426,12 +3426,12 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
     if (RecordCallTarget()) {
       // If there is a call target cache, mark it megamorphic in the
       // non-function case. MegamorphicSentinel is an immortal immovable object
-      // (undefined) so no write barrier is needed.
+      // (megamorphic symbol) so no write barrier is needed.
       ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
-                masm->isolate()->heap()->undefined_value());
+                masm->isolate()->heap()->megamorphic_symbol());
       __ Add(x12, cache_cell, Operand::UntagSmiAndScale(slot,
                                                         kPointerSizeLog2));
-      __ LoadRoot(x11, Heap::kUndefinedValueRootIndex);
+      __ LoadRoot(x11, Heap::kMegamorphicSymbolRootIndex);
       __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize));
     }
     // Check for function proxy.
@@ -3477,7 +3477,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
   // x0 : number of arguments
   // x1 : the function to call
   // x2 : feedback vector
-  // x3 : slot in feedback vector (smi) (if r2 is not undefined)
+  // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
   Register function = x1;
   Label slow, non_function_call;
 
@@ -5489,7 +5489,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- x0 : argc (only if argument_count_ == ANY)
   //  -- x1 : constructor
-  //  -- x2 : feedback vector (fixed array or undefined)
+  //  -- x2 : feedback vector (fixed array or the megamorphic symbol)
   //  -- x3 : slot index (if x2 is fixed array)
   //  -- sp[0] : return address
   //  -- sp[4] : last argument
@@ -5498,6 +5498,9 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   Register feedback_vector = x2;
   Register slot_index = x3;
 
+  ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
+            masm->isolate()->heap()->megamorphic_symbol());
+
   if (FLAG_debug_code) {
     // The array construct code is only set for the global and natives
     // builtin Array functions which always have maps.
@@ -5513,10 +5516,12 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
     __ Abort(kUnexpectedInitialMapForArrayFunction);
     __ Bind(&map_ok);
 
-    // In feedback_vector, we expect either undefined or a valid fixed array.
+    // In feedback_vector, we expect either the megamorphic symbol or a valid
+    // fixed array.
     Label okay_here;
     Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
-    __ JumpIfRoot(feedback_vector, Heap::kUndefinedValueRootIndex, &okay_here);
+    __ JumpIfRoot(feedback_vector, Heap::kMegamorphicSymbolRootIndex,
+                  &okay_here);
     __ Ldr(x10, FieldMemOperand(feedback_vector, FixedArray::kMapOffset));
     __ Cmp(x10, Operand(fixed_array_map));
     __ Assert(eq, kExpectedFixedArrayInFeedbackVector);
@@ -5531,14 +5536,15 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   Register kind = x3;
   Label no_info;
   // Get the elements kind and case on that.
-  __ JumpIfRoot(feedback_vector, Heap::kUndefinedValueRootIndex, &no_info);
+  __ JumpIfRoot(feedback_vector, Heap::kMegamorphicSymbolRootIndex, &no_info);
   __ Add(feedback_vector, feedback_vector,
          Operand::UntagSmiAndScale(slot_index, kPointerSizeLog2));
   __ Ldr(allocation_site, FieldMemOperand(feedback_vector,
                                           FixedArray::kHeaderSize));
 
-  // If the feedback vector is undefined, or contains anything other than an
-  // AllocationSite, call an array constructor that doesn't use AllocationSites.
+  // If the feedback vector is the megamorphic symbol, or contains anything
+  // other than an AllocationSite, call an array constructor that doesn't
+  // use AllocationSites.
   __ Ldr(x10, FieldMemOperand(allocation_site, AllocationSite::kMapOffset));
   __ JumpIfNotRoot(x10, Heap::kAllocationSiteMapRootIndex, &no_info);
 
index 6086626..677f2b2 100644 (file)
@@ -441,8 +441,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
 
   __ Mov(x0, instr->arity());
   // No cell in x2 for construct type feedback in optimized code.
-  Handle<Object> undefined_value(isolate()->factory()->undefined_value());
-  __ Mov(x2, Operand(undefined_value));
+  Handle<Object> megamorphic_symbol =
+      TypeFeedbackInfo::MegamorphicSentinel(isolate());
+  __ Mov(x2, Operand(megamorphic_symbol));
 
   CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
   CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
@@ -457,7 +458,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
   ASSERT(ToRegister(instr->constructor()).is(x1));
 
   __ Mov(x0, Operand(instr->arity()));
-  __ Mov(x2, Operand(factory()->undefined_value()));
+  __ Mov(x2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
 
   ElementsKind kind = instr->hydrogen()->elements_kind();
   AllocationSiteOverrideMode override_mode =
index 7898086..e9aec8e 100644 (file)
@@ -155,10 +155,9 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
 
   // Run the native code for the Array function called as a normal function.
   // tail call a stub
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
-  __ mov(r2, Operand(undefined_sentinel));
+  Handle<Object> megamorphic_sentinel =
+      TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+  __ mov(r2, Operand(megamorphic_sentinel));
   ArrayConstructorStub stub(masm->isolate());
   __ TailCallStub(&stub);
 }
@@ -738,9 +737,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
     __ mov(r0, Operand(r3));
     if (is_construct) {
       // No type feedback cell is available
-      Handle<Object> undefined_sentinel(
-          masm->isolate()->heap()->undefined_value(), masm->isolate());
-      __ mov(r2, Operand(undefined_sentinel));
+      Handle<Object> megamorphic_sentinel =
+          TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+      __ mov(r2, Operand(megamorphic_sentinel));
       CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
       __ CallStub(&stub);
     } else {
index 5ac17a0..b933c4a 100644 (file)
@@ -3015,9 +3015,9 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
   Label initialize, done, miss, megamorphic, not_array_function;
 
   ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
-            masm->isolate()->heap()->undefined_value());
+            masm->isolate()->heap()->megamorphic_symbol());
   ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
-            masm->isolate()->heap()->the_hole_value());
+            masm->isolate()->heap()->uninitialized_symbol());
 
   // Load the cache state into r4.
   __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
@@ -3046,13 +3046,13 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
 
   // A monomorphic miss (i.e, here the cache is not uninitialized) goes
   // megamorphic.
-  __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
+  __ CompareRoot(r4, Heap::kUninitializedSymbolRootIndex);
   __ b(eq, &initialize);
   // MegamorphicSentinel is an immortal immovable object (undefined) so no
   // write-barrier is needed.
   __ bind(&megamorphic);
   __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
-  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
   __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
   __ jmp(&done);
 
@@ -3099,7 +3099,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
 void CallFunctionStub::Generate(MacroAssembler* masm) {
   // r1 : the function to call
   // r2 : feedback vector
-  // r3 : (only if r2 is not undefined) slot in feedback vector (Smi)
+  // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
+  //      vector (Smi)
   Label slow, non_function, wrap, cont;
 
   if (NeedsChecks()) {
@@ -3155,11 +3156,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
     if (RecordCallTarget()) {
       // If there is a call target cache, mark it megamorphic in the
       // non-function case.  MegamorphicSentinel is an immortal immovable
-      // object (undefined) so no write barrier is needed.
+      // object (megamorphic symbol) so no write barrier is needed.
       ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
-                masm->isolate()->heap()->undefined_value());
+                masm->isolate()->heap()->megamorphic_symbol());
       __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
-      __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+      __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
       __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
     }
     // Check for function proxy.
@@ -3204,7 +3205,8 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
   // r0 : number of arguments
   // r1 : the function to call
   // r2 : feedback vector
-  // r3 : (only if r2 is not undefined) slot in feedback vector (Smi)
+  // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
+  //      vector (Smi)
   Label slow, non_function_call;
 
   // Check that the function is not a smi.
@@ -5289,11 +5291,15 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r0 : argc (only if argument_count_ == ANY)
   //  -- r1 : constructor
-  //  -- r2 : feedback vector (fixed array or undefined)
+  //  -- r2 : feedback vector (fixed array or megamorphic symbol)
   //  -- r3 : slot index (if r2 is fixed array)
   //  -- sp[0] : return address
   //  -- sp[4] : last argument
   // -----------------------------------
+
+  ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
+            masm->isolate()->heap()->megamorphic_symbol());
+
   if (FLAG_debug_code) {
     // The array construct code is only set for the global and natives
     // builtin Array functions which always have maps.
@@ -5306,10 +5312,11 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
     __ CompareObjectType(r4, r4, r5, MAP_TYPE);
     __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
 
-    // We should either have undefined in ebx or a valid fixed array.
+    // We should either have the megamorphic symbol in ebx or a valid
+    // fixed array.
     Label okay_here;
     Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
-    __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
+    __ CompareRoot(r2, Heap::kMegamorphicSymbolRootIndex);
     __ b(eq, &okay_here);
     __ ldr(r4, FieldMemOperand(r2, 0));
     __ cmp(r4, Operand(fixed_array_map));
@@ -5323,7 +5330,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
 
   Label no_info;
   // Get the elements kind and case on that.
-  __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
+  __ CompareRoot(r2, Heap::kMegamorphicSymbolRootIndex);
   __ b(eq, &no_info);
   __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3));
   __ ldr(r2, FieldMemOperand(r2, FixedArray::kHeaderSize));
index ca20423..f9346ab 100644 (file)
@@ -3961,8 +3961,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
 
   __ mov(r0, Operand(instr->arity()));
   // No cell in r2 for construct type feedback in optimized code
-  Handle<Object> undefined_value(isolate()->factory()->undefined_value());
-  __ mov(r2, Operand(undefined_value));
+  Handle<Object> megamorphic_symbol =
+      TypeFeedbackInfo::MegamorphicSentinel(isolate());
+  __ mov(r2, Operand(megamorphic_symbol));
   CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
   CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
 }
@@ -3974,7 +3975,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
   ASSERT(ToRegister(instr->result()).is(r0));
 
   __ mov(r0, Operand(instr->arity()));
-  __ mov(r2, Operand(factory()->undefined_value()));
+  __ mov(r2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
   ElementsKind kind = instr->hydrogen()->elements_kind();
   AllocationSiteOverrideMode override_mode =
       (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
index c51e4d4..6291f4e 100644 (file)
@@ -388,10 +388,13 @@ unsigned FullCodeGenerator::EmitBackEdgeTable() {
 
 void FullCodeGenerator::InitializeFeedbackVector() {
   int length = info_->function()->slot_count();
-  ASSERT_EQ(isolate()->heap()->the_hole_value(),
-            *TypeFeedbackInfo::UninitializedSentinel(isolate()));
-  feedback_vector_ = isolate()->factory()->NewFixedArrayWithHoles(length,
-                                                                  TENURED);
+  feedback_vector_ = isolate()->factory()->NewFixedArray(length, TENURED);
+  Handle<Object> sentinel = TypeFeedbackInfo::UninitializedSentinel(isolate());
+  // Ensure that it's safe to set without using a write barrier.
+  ASSERT_EQ(isolate()->heap()->uninitialized_symbol(), *sentinel);
+  for (int i = 0; i < length; i++) {
+    feedback_vector_->set(i, *sentinel, SKIP_WRITE_BARRIER);
+  }
 }
 
 
index 5e40ef5..2d6b16e 100644 (file)
@@ -3315,6 +3315,18 @@ bool Heap::CreateInitialObjects() {
   Symbol::cast(obj)->set_is_private(true);
   set_elements_transition_symbol(Symbol::cast(obj));
 
+  { MaybeObject* maybe_obj = AllocateSymbol();
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  Symbol::cast(obj)->set_is_private(true);
+  set_uninitialized_symbol(Symbol::cast(obj));
+
+  { MaybeObject* maybe_obj = AllocateSymbol();
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  Symbol::cast(obj)->set_is_private(true);
+  set_megamorphic_symbol(Symbol::cast(obj));
+
   { MaybeObject* maybe_obj = SeededNumberDictionary::Allocate(this, 0, TENURED);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
index 05683a8..f99bb51 100644 (file)
@@ -196,6 +196,8 @@ namespace internal {
   V(SeededNumberDictionary, empty_slow_element_dictionary,                     \
       EmptySlowElementDictionary)                                              \
   V(Symbol, observed_symbol, ObservedSymbol)                                   \
+  V(Symbol, uninitialized_symbol, UninitializedSymbol)                         \
+  V(Symbol, megamorphic_symbol, MegamorphicSymbol)                             \
   V(FixedArray, materialized_objects, MaterializedObjects)                     \
   V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad)        \
   V(JSObject, microtask_state, MicrotaskState)
index d748d23..38c99e4 100644 (file)
@@ -473,9 +473,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
     // Invoke the code.
     if (is_construct) {
       // No type feedback cell is available
-      Handle<Object> undefined_sentinel(
-          masm->isolate()->heap()->undefined_value(), masm->isolate());
-      __ mov(ebx, Immediate(undefined_sentinel));
+      Handle<Object> megamorphic_sentinel =
+          TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+      __ mov(ebx, Immediate(megamorphic_sentinel));
       CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
       __ CallStub(&stub);
     } else {
@@ -1057,10 +1057,9 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
 
   // Run the native code for the Array function called as a normal function.
   // tail call a stub
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
-  __ mov(ebx, Immediate(undefined_sentinel));
+  Handle<Object> megamorphic_sentinel =
+      TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+  __ mov(ebx, Immediate(megamorphic_sentinel));
   ArrayConstructorStub stub(masm->isolate());
   __ TailCallStub(&stub);
 }
index 5c9056a..d1725bb 100644 (file)
@@ -2423,7 +2423,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
 
 void CallFunctionStub::Generate(MacroAssembler* masm) {
   // ebx : feedback vector
-  // edx : (only if ebx is not undefined) slot in feedback vector (Smi)
+  // edx : (only if ebx is not the megamorphic symbol) slot in feedback
+  //       vector (Smi)
   // edi : the function to call
   Isolate* isolate = masm->isolate();
   Label slow, non_function, wrap, cont;
@@ -2481,7 +2482,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
     if (RecordCallTarget()) {
       // If there is a call target cache, mark it megamorphic in the
       // non-function case.  MegamorphicSentinel is an immortal immovable
-      // object (undefined) so no write barrier is needed.
+      // object (megamorphic symbol) so no write barrier is needed.
       __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
                           FixedArray::kHeaderSize),
              Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
@@ -2529,7 +2530,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 void CallConstructStub::Generate(MacroAssembler* masm) {
   // eax : number of arguments
   // ebx : feedback vector
-  // edx : (only if ebx is not undefined) slot in feedback vector (Smi)
+  // edx : (only if ebx is not the megamorphic symbol) slot in feedback
+  //       vector (Smi)
   // edi : constructor function
   Label slow, non_function_call;
 
@@ -5145,15 +5147,14 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax : argc (only if argument_count_ == ANY)
-  //  -- ebx : feedback vector (fixed array or undefined)
+  //  -- ebx : feedback vector (fixed array or megamorphic symbol)
   //  -- edx : slot index (if ebx is fixed array)
   //  -- edi : constructor
   //  -- esp[0] : return address
   //  -- esp[4] : last argument
   // -----------------------------------
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
+  Handle<Object> megamorphic_sentinel =
+      TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
 
   if (FLAG_debug_code) {
     // The array construct code is only set for the global and natives
@@ -5167,24 +5168,26 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
     __ CmpObjectType(ecx, MAP_TYPE, ecx);
     __ Assert(equal, kUnexpectedInitialMapForArrayFunction);
 
-    // We should either have undefined in ebx or a valid fixed array.
+    // We should either have the megamorphic symbol in ebx or a valid
+    // fixed array.
     Label okay_here;
     Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
-    __ cmp(ebx, Immediate(undefined_sentinel));
+    __ cmp(ebx, Immediate(megamorphic_sentinel));
     __ j(equal, &okay_here);
     __ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map));
     __ Assert(equal, kExpectedFixedArrayInRegisterEbx);
 
-    // edx should be a smi if we don't have undefined in ebx.
+    // edx should be a smi if we don't have the megamorphic symbol in ebx.
     __ AssertSmi(edx);
 
     __ bind(&okay_here);
   }
 
   Label no_info;
-  // If the feedback vector is undefined, or contains anything other than an
-  // AllocationSite, call an array constructor that doesn't use AllocationSites.
-  __ cmp(ebx, Immediate(undefined_sentinel));
+  // If the feedback vector is the megamorphic sentinel, or contains anything
+  // other than an AllocationSite, call an array constructor that doesn't use
+  // AllocationSites.
+  __ cmp(ebx, Immediate(megamorphic_sentinel));
   __ j(equal, &no_info);
   __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
                            FixedArray::kHeaderSize));
index f446e22..6b6b5e6 100644 (file)
@@ -4192,8 +4192,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
   ASSERT(ToRegister(instr->result()).is(eax));
 
   // No cell in ebx for construct type feedback in optimized code
-  Handle<Object> undefined_value(isolate()->factory()->undefined_value());
-  __ mov(ebx, Immediate(undefined_value));
+  Handle<Object> megamorphic_symbol =
+      TypeFeedbackInfo::MegamorphicSentinel(isolate());
+  __ mov(ebx, Immediate(megamorphic_symbol));
   CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
   __ Set(eax, Immediate(instr->arity()));
   CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
@@ -4206,7 +4207,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
   ASSERT(ToRegister(instr->result()).is(eax));
 
   __ Set(eax, Immediate(instr->arity()));
-  __ mov(ebx, factory()->undefined_value());
+  __ mov(ebx, TypeFeedbackInfo::MegamorphicSentinel(isolate()));
   ElementsKind kind = instr->hydrogen()->elements_kind();
   AllocationSiteOverrideMode override_mode =
       (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
index 767aa9c..a73dc5b 100644 (file)
@@ -6526,12 +6526,12 @@ MaybeObject* ConstantPoolArray::Copy() {
 
 
 Handle<Object> TypeFeedbackInfo::UninitializedSentinel(Isolate* isolate) {
-  return isolate->factory()->the_hole_value();
+  return isolate->factory()->uninitialized_symbol();
 }
 
 
 Handle<Object> TypeFeedbackInfo::MegamorphicSentinel(Isolate* isolate) {
-  return isolate->factory()->undefined_value();
+  return isolate->factory()->megamorphic_symbol();
 }
 
 
@@ -6542,7 +6542,7 @@ Handle<Object> TypeFeedbackInfo::MonomorphicArraySentinel(Isolate* isolate,
 
 
 Object* TypeFeedbackInfo::RawUninitializedSentinel(Heap* heap) {
-  return heap->the_hole_value();
+  return heap->uninitialized_symbol();
 }
 
 
index f4be791..47d6042 100644 (file)
@@ -14825,7 +14825,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
 
   Handle<AllocationSite> site;
   if (!type_info.is_null() &&
-      *type_info != isolate->heap()->undefined_value()) {
+      !type_info.is_identical_to(
+          TypeFeedbackInfo::MegamorphicSentinel(isolate))) {
     site = Handle<AllocationSite>::cast(type_info);
     ASSERT(!site->SitePointsToLiteral());
   }
index 6717dd5..5345e9e 100644 (file)
@@ -533,9 +533,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
     // Invoke the code.
     if (is_construct) {
       // No type feedback cell is available
-      Handle<Object> undefined_sentinel(
-          masm->isolate()->factory()->undefined_value());
-      __ Move(rbx, undefined_sentinel);
+      Handle<Object> megamorphic_sentinel =
+          TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+      __ Move(rbx, megamorphic_sentinel);
       // Expects rdi to hold function pointer.
       CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
       __ CallStub(&stub);
@@ -1128,10 +1128,9 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
 
   // Run the native code for the Array function called as a normal function.
   // tail call a stub
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
-  __ Move(rbx, undefined_sentinel);
+  Handle<Object> megamorphic_sentinel =
+      TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
+  __ Move(rbx, megamorphic_sentinel);
   ArrayConstructorStub stub(masm->isolate());
   __ TailCallStub(&stub);
 }
index bced059..d6b0dd0 100644 (file)
@@ -2267,7 +2267,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
 
 void CallFunctionStub::Generate(MacroAssembler* masm) {
   // rbx : feedback vector
-  // rdx : (only if rbx is not undefined) slot in feedback vector (Smi)
+  // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
+  //       vector (Smi)
   // rdi : the function to call
   Isolate* isolate = masm->isolate();
   Label slow, non_function, wrap, cont;
@@ -2327,7 +2328,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
     if (RecordCallTarget()) {
       // If there is a call target cache, mark it megamorphic in the
       // non-function case.  MegamorphicSentinel is an immortal immovable
-      // object (undefined) so no write barrier is needed.
+      // object (megamorphic symbol) so no write barrier is needed.
       __ SmiToInteger32(rdx, rdx);
       __ Move(FieldOperand(rbx, rdx, times_pointer_size,
                            FixedArray::kHeaderSize),
@@ -2379,7 +2380,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 void CallConstructStub::Generate(MacroAssembler* masm) {
   // rax : number of arguments
   // rbx : feedback vector
-  // rdx : (only if rbx is not undefined) slot in feedback vector (Smi)
+  // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
+  //       vector (Smi)
   // rdi : constructor function
   Label slow, non_function_call;
 
@@ -4995,15 +4997,14 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : argc
-  //  -- rbx    : feedback vector (fixed array or undefined)
+  //  -- rbx    : feedback vector (fixed array or megamorphic symbol)
   //  -- rdx    : slot index (if ebx is fixed array)
   //  -- rdi    : constructor
   //  -- rsp[0] : return address
   //  -- rsp[8] : last argument
   // -----------------------------------
-  Handle<Object> undefined_sentinel(
-      masm->isolate()->heap()->undefined_value(),
-      masm->isolate());
+  Handle<Object> megamorphic_sentinel =
+      TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
 
   if (FLAG_debug_code) {
     // The array construct code is only set for the global and natives
@@ -5018,24 +5019,26 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
     __ CmpObjectType(rcx, MAP_TYPE, rcx);
     __ Check(equal, kUnexpectedInitialMapForArrayFunction);
 
-    // We should either have undefined in rbx or a valid fixed array.
+    // We should either have the megamorphic symbol in rbx or a valid
+    // fixed array.
     Label okay_here;
     Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
-    __ Cmp(rbx, undefined_sentinel);
+    __ Cmp(rbx, megamorphic_sentinel);
     __ j(equal, &okay_here);
     __ Cmp(FieldOperand(rbx, 0), fixed_array_map);
     __ Assert(equal, kExpectedFixedArrayInRegisterRbx);
 
-    // rdx should be a smi if we don't have undefined in rbx.
+    // rdx should be a smi if we don't have the megamorphic symbol in rbx.
     __ AssertSmi(rdx);
 
     __ bind(&okay_here);
   }
 
   Label no_info;
-  // If the feedback slot is undefined, or contains anything other than an
-  // AllocationSite, call an array constructor that doesn't use AllocationSites.
-  __ Cmp(rbx, undefined_sentinel);
+  // If the feedback slot is the megamorphic sentinel, or contains anything
+  // other than an AllocationSite, call an array constructor that doesn't use
+  // AllocationSites.
+  __ Cmp(rbx, megamorphic_sentinel);
   __ j(equal, &no_info);
   __ SmiToInteger32(rdx, rdx);
   __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
index ca50c9e..d6c2f97 100644 (file)
@@ -3785,8 +3785,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
 
   __ Set(rax, instr->arity());
   // No cell in ebx for construct type feedback in optimized code
-  Handle<Object> undefined_value(isolate()->factory()->undefined_value());
-  __ Move(rbx, undefined_value);
+  Handle<Object> megamorphic_symbol =
+      TypeFeedbackInfo::MegamorphicSentinel(isolate());
+  __ Move(rbx, megamorphic_symbol);
   CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
   CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
 }
@@ -3798,7 +3799,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
   ASSERT(ToRegister(instr->result()).is(rax));
 
   __ Set(rax, instr->arity());
-  __ Move(rbx, factory()->undefined_value());
+  __ Move(rbx, TypeFeedbackInfo::MegamorphicSentinel(isolate()));
   ElementsKind kind = instr->hydrogen()->elements_kind();
   AllocationSiteOverrideMode override_mode =
       (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
index b3058f7..059fd8f 100644 (file)
@@ -2866,8 +2866,10 @@ TEST(IncrementalMarkingClearsTypeFeedbackInfo) {
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
 
   CHECK_EQ(2, feedback_vector->length());
-  CHECK(feedback_vector->get(0)->IsTheHole());
-  CHECK(feedback_vector->get(1)->IsTheHole());
+  CHECK_EQ(feedback_vector->get(0),
+           *TypeFeedbackInfo::UninitializedSentinel(CcTest::i_isolate()));
+  CHECK_EQ(feedback_vector->get(1),
+           *TypeFeedbackInfo::UninitializedSentinel(CcTest::i_isolate()));
 }