Revision: 19712
Author:   [email protected]
Date:     Fri Mar  7 10:12:17 2014 UTC
Log:      Moved type feedback vector to SharedFunctionInfo.

Type Vector followup: the type vector currently lives off the code object. This CL moves it to the SharedFunctionInfo, facilitating re-use and continued use in crankshafted code if desired.

[email protected]

Review URL: https://codereview.chromium.org/178463007
http://code.google.com/p/v8/source/detail?r=19712

Modified:
 /branches/bleeding_edge/src/a64/full-codegen-a64.cc
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/compiler.cc
 /branches/bleeding_edge/src/compiler.h
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/factory.h
 /branches/bleeding_edge/src/full-codegen.cc
 /branches/bleeding_edge/src/full-codegen.h
 /branches/bleeding_edge/src/heap-snapshot-generator.cc
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/mips/full-codegen-mips.cc
 /branches/bleeding_edge/src/objects-debug.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects-printer.cc
 /branches/bleeding_edge/src/objects-visiting-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/type-info.cc
 /branches/bleeding_edge/src/type-info.h
 /branches/bleeding_edge/src/typing.cc
 /branches/bleeding_edge/src/x64/full-codegen-x64.cc
 /branches/bleeding_edge/test/cctest/test-compiler.cc
 /branches/bleeding_edge/test/cctest/test-heap.cc

=======================================
--- /branches/bleeding_edge/src/a64/full-codegen-a64.cc Fri Mar 7 09:19:51 2014 UTC +++ /branches/bleeding_edge/src/a64/full-codegen-a64.cc Fri Mar 7 10:12:17 2014 UTC
@@ -129,8 +129,6 @@
   handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);

-  InitializeFeedbackVector();
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -1162,12 +1160,8 @@
   // We got a fixed array in register x0. Iterate through that.
   __ Bind(&fixed_array);

-  Handle<Object> feedback = Handle<Object>(
-      Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
-      isolate());
-  StoreFeedbackVectorSlot(slot, feedback);
   __ LoadObject(x1, FeedbackVector());
- __ Mov(x10, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+  __ Mov(x10, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
   __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot)));

   __ Mov(x1, Operand(Smi::FromInt(1)));  // Smi indicates slow check.
@@ -2415,9 +2409,6 @@
   // Record source position for debugger.
   SetSourcePosition(expr->position());

-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
   __ LoadObject(x2, FeedbackVector());
   __ Mov(x3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));

@@ -2614,9 +2605,6 @@
   __ Peek(x1, arg_count * kXRegSizeInBytes);

   // Record call targets in unoptimized code.
-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
   __ LoadObject(x2, FeedbackVector());
   __ Mov(x3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));

=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Tue Mar 4 12:48:17 2014 UTC +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Mar 7 10:12:17 2014 UTC
@@ -131,8 +131,6 @@
   handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);

-  InitializeFeedbackVector();
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -1167,12 +1165,8 @@
   Label non_proxy;
   __ bind(&fixed_array);

-  Handle<Object> feedback = Handle<Object>(
-      Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
-      isolate());
-  StoreFeedbackVectorSlot(slot, feedback);
   __ Move(r1, FeedbackVector());
- __ mov(r2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+  __ mov(r2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
   __ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot)));

   __ mov(r1, Operand(Smi::FromInt(1)));  // Smi indicates slow check
@@ -2714,9 +2708,6 @@
   // Record source position for debugger.
   SetSourcePosition(expr->position());

-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
   __ Move(r2, FeedbackVector());
   __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));

@@ -2903,9 +2894,6 @@
   __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));

   // Record call targets in unoptimized code.
-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
   __ Move(r2, FeedbackVector());
   __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));

=======================================
--- /branches/bleeding_edge/src/compiler.cc     Fri Mar  7 08:43:54 2014 UTC
+++ /branches/bleeding_edge/src/compiler.cc     Fri Mar  7 10:12:17 2014 UTC
@@ -141,6 +141,15 @@
     SetLanguageMode(shared_info_->language_mode());
   }
   set_bailout_reason(kUnknown);
+
+  if (!shared_info().is_null()) {
+    FixedArray* info_feedback_vector = shared_info()->feedback_vector();
+    if (info_feedback_vector->length() > 0) {
+      // We should initialize the CompilationInfo feedback vector from the
+      // passed in shared info, rather than creating a new one.
+      feedback_vector_ = Handle<FixedArray>(info_feedback_vector, isolate);
+    }
+  }
 }


@@ -250,6 +259,20 @@
   ASSERT(scope_ == NULL);
   scope_ = scope;
   function()->ProcessFeedbackSlots(isolate_);
+  int length = function()->slot_count();
+  if (feedback_vector_.is_null()) {
+    // Allocate the feedback vector too.
+ feedback_vector_ = isolate()->factory()->NewFixedArray(length, TENURED);
+    // Ensure we can skip the write barrier
+    ASSERT_EQ(isolate()->heap()->uninitialized_symbol(),
+              *TypeFeedbackInfo::UninitializedSentinel(isolate()));
+    for (int i = 0; i < length; i++) {
+      feedback_vector_->set(i,
+          *TypeFeedbackInfo::UninitializedSentinel(isolate()),
+          SKIP_WRITE_BARRIER);
+    }
+  }
+  ASSERT(feedback_vector_->length() == length);
 }


@@ -571,6 +594,8 @@
   shared->ReplaceCode(*code);
   if (shared->optimization_disabled()) code->set_optimizable(false);

+  shared->set_feedback_vector(*info->feedback_vector());
+
   // Set the expected number of properties for instances.
   FunctionLiteral* lit = info->function();
   int expected = lit->expected_property_count();
@@ -826,7 +851,8 @@
         lit->materialized_literal_count(),
         lit->is_generator(),
         info->code(),
-        ScopeInfo::Create(info->scope(), info->zone()));
+        ScopeInfo::Create(info->scope(), info->zone()),
+        info->feedback_vector());

     ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
     SetFunctionInfo(result, lit, true, script);
@@ -1033,7 +1059,8 @@
                                      literal->materialized_literal_count(),
                                      literal->is_generator(),
                                      info.code(),
-                                     scope_info);
+                                     scope_info,
+                                     info.feedback_vector());
   SetFunctionInfo(result, literal, false, script);
   RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
   result->set_allows_lazy_compilation(allow_lazy);
=======================================
--- /branches/bleeding_edge/src/compiler.h      Fri Mar  7 08:43:54 2014 UTC
+++ /branches/bleeding_edge/src/compiler.h      Fri Mar  7 10:12:17 2014 UTC
@@ -181,6 +181,9 @@
     ASSERT(global_scope_ == NULL);
     global_scope_ = global_scope;
   }
+  Handle<FixedArray> feedback_vector() const {
+    return feedback_vector_;
+  }
   void SetCode(Handle<Code> code) { code_ = code; }
   void SetExtension(v8::Extension* extension) {
     ASSERT(!is_lazy());
@@ -409,6 +412,9 @@
   // global script. Will be a null handle otherwise.
   Handle<Context> context_;

+  // Used by codegen, ultimately kept rooted by the SharedFunctionInfo.
+  Handle<FixedArray> feedback_vector_;
+
   // Compilation mode flag and whether deoptimization is allowed.
   Mode mode_;
   BailoutId osr_ast_id_;
=======================================
--- /branches/bleeding_edge/src/factory.cc      Fri Mar  7 08:43:54 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc      Fri Mar  7 10:12:17 2014 UTC
@@ -1541,10 +1541,12 @@
     int number_of_literals,
     bool is_generator,
     Handle<Code> code,
-    Handle<ScopeInfo> scope_info) {
+    Handle<ScopeInfo> scope_info,
+    Handle<FixedArray> feedback_vector) {
   Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
   shared->set_code(*code);
   shared->set_scope_info(*scope_info);
+  shared->set_feedback_vector(*feedback_vector);
   int literals_array_size = number_of_literals;
   // If the function contains object, regexp or array literals,
   // allocate extra space for a literals array prefix containing the
=======================================
--- /branches/bleeding_edge/src/factory.h       Thu Feb 13 08:43:53 2014 UTC
+++ /branches/bleeding_edge/src/factory.h       Fri Mar  7 10:12:17 2014 UTC
@@ -516,7 +516,8 @@
       int number_of_literals,
       bool is_generator,
       Handle<Code> code,
-      Handle<ScopeInfo> scope_info);
+      Handle<ScopeInfo> scope_info,
+      Handle<FixedArray> feedback_vector);
   Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);

   Handle<JSMessageObject> NewJSMessageObject(
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Fri Mar  7 09:49:28 2014 UTC
+++ /branches/bleeding_edge/src/full-codegen.cc Fri Mar  7 10:12:17 2014 UTC
@@ -384,18 +384,6 @@
   }
   return offset;
 }
-
-
-void FullCodeGenerator::InitializeFeedbackVector() {
-  int length = info_->function()->slot_count();
-  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);
-  }
-}


 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
@@ -416,7 +404,6 @@
 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
   info->set_ic_total_count(ic_total_count_);
-  info->set_feedback_vector(*FeedbackVector());
   ASSERT(!isolate()->heap()->InNewSpace(*info));
   code->set_type_feedback_info(*info);
 }
@@ -1590,7 +1577,8 @@
   bool is_generator = false;
   Handle<SharedFunctionInfo> shared =
isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
-          code, Handle<ScopeInfo>(fun->shared()->scope_info()));
+          code, Handle<ScopeInfo>(fun->shared()->scope_info()),
+          Handle<FixedArray>(fun->shared()->feedback_vector()));
   shared->set_construct_stub(*construct_stub);

   // Copy the function data to the shared function info.
=======================================
--- /branches/bleeding_edge/src/full-codegen.h  Fri Mar  7 08:49:02 2014 UTC
+++ /branches/bleeding_edge/src/full-codegen.h  Fri Mar  7 10:12:17 2014 UTC
@@ -437,12 +437,8 @@
// Feedback slot support. The feedback vector will be cleared during gc and
   // collected by the type-feedback oracle.
   Handle<FixedArray> FeedbackVector() {
-    return feedback_vector_;
+    return info_->feedback_vector();
   }
-  void StoreFeedbackVectorSlot(int slot, Handle<Object> object) {
-    feedback_vector_->set(slot, *object);
-  }
-  void InitializeFeedbackVector();

   // Record a call's return site offset, used to rebuild the frame if the
   // called function was inlined at the site.
@@ -848,7 +844,6 @@
   ZoneList<BackEdgeEntry> back_edges_;
   int ic_total_count_;
   Handle<FixedArray> handler_table_;
-  Handle<FixedArray> feedback_vector_;
   Handle<Cell> profiling_counter_;
   bool generate_debug_code_;

=======================================
--- /branches/bleeding_edge/src/heap-snapshot-generator.cc Fri Mar 7 08:43:54 2014 UTC +++ /branches/bleeding_edge/src/heap-snapshot-generator.cc Fri Mar 7 10:12:17 2014 UTC
@@ -1327,6 +1327,9 @@
   SetInternalReference(obj, entry,
                        "optimized_code_map", shared->optimized_code_map(),
                        SharedFunctionInfo::kOptimizedCodeMapOffset);
+  SetInternalReference(obj, entry,
+                       "feedback_vector", shared->feedback_vector(),
+                       SharedFunctionInfo::kFeedbackVectorOffset);
   SetWeakReference(obj, entry,
                    "initial_map", shared->initial_map(),
                    SharedFunctionInfo::kInitialMapOffset);
=======================================
--- /branches/bleeding_edge/src/heap.cc Fri Mar  7 09:10:18 2014 UTC
+++ /branches/bleeding_edge/src/heap.cc Fri Mar  7 10:12:17 2014 UTC
@@ -2684,7 +2684,6 @@
     if (!maybe_info->To(&info)) return maybe_info;
   }
   info->initialize_storage();
-  info->set_feedback_vector(empty_fixed_array(), SKIP_WRITE_BARRIER);
   return info;
 }

@@ -3806,6 +3805,7 @@
   share->set_script(undefined_value(), SKIP_WRITE_BARRIER);
   share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER);
   share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
+  share->set_feedback_vector(empty_fixed_array(), SKIP_WRITE_BARRIER);
   share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
   share->set_ast_node_count(0);
   share->set_counters(0);
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri Mar  7 09:49:28 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Mar  7 10:12:17 2014 UTC
@@ -7210,6 +7210,7 @@
       target_shared->set_scope_info(*target_scope_info);
     }
     target_shared->EnableDeoptimizationSupport(*target_info.code());
+    target_shared->set_feedback_vector(*target_info.feedback_vector());
     Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
                                         &target_info,
                                         target_shared);
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Mar 7 08:36:53 2014 UTC +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Mar 7 10:12:17 2014 UTC
@@ -119,8 +119,6 @@
   handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);

-  InitializeFeedbackVector();
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -1104,15 +1102,10 @@
   Label non_proxy;
   __ bind(&fixed_array);

-  Handle<Object> feedback = Handle<Object>(
-      Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
-      isolate());
-  StoreFeedbackVectorSlot(slot, feedback);
-
// No need for a write barrier, we are storing a Smi in the feedback vector.
   __ LoadHeapObject(ebx, FeedbackVector());
   __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)),
-         Immediate(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+         Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate())));

   __ mov(ebx, Immediate(Smi::FromInt(1)));  // Smi indicates slow check
   __ mov(ecx, Operand(esp, 0 * kPointerSize));  // Get enumerated object
@@ -2666,9 +2659,6 @@
   // Record source position for debugger.
   SetSourcePosition(expr->position());

-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
   __ LoadHeapObject(ebx, FeedbackVector());
   __ mov(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));

@@ -2846,9 +2836,6 @@
   __ mov(edi, Operand(esp, arg_count * kPointerSize));

   // Record call targets in unoptimized code.
-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
   __ LoadHeapObject(ebx, FeedbackVector());
   __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));

=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Tue Mar 4 20:22:56 2014 UTC +++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Fri Mar 7 10:12:17 2014 UTC
@@ -139,8 +139,6 @@
   handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);

-  InitializeFeedbackVector();
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -1176,12 +1174,8 @@
   Label non_proxy;
   __ bind(&fixed_array);

-  Handle<Object> feedback = Handle<Object>(
-      Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
-      isolate());
-  StoreFeedbackVectorSlot(slot, feedback);
   __ li(a1, FeedbackVector());
-  __ li(a2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+  __ li(a2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
   __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));

   __ li(a1, Operand(Smi::FromInt(1)));  // Smi indicates slow check
@@ -2737,9 +2731,6 @@
   // Record source position for debugger.
   SetSourcePosition(expr->position());

-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
   __ li(a2, FeedbackVector());
   __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));

@@ -2924,9 +2915,6 @@
   __ lw(a1, MemOperand(sp, arg_count * kPointerSize));

   // Record call targets in unoptimized code.
-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
   __ li(a2, FeedbackVector());
   __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));

=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Fri Mar 7 08:43:54 2014 UTC +++ /branches/bleeding_edge/src/objects-debug.cc Fri Mar 7 10:12:17 2014 UTC
@@ -368,7 +368,6 @@
 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
   VerifyObjectField(kStorage1Offset);
   VerifyObjectField(kStorage2Offset);
-  VerifyHeapPointer(feedback_vector());
 }


@@ -545,6 +544,7 @@
   VerifyObjectField(kNameOffset);
   VerifyObjectField(kCodeOffset);
   VerifyObjectField(kOptimizedCodeMapOffset);
+  VerifyObjectField(kFeedbackVectorOffset);
   VerifyObjectField(kScopeInfoOffset);
   VerifyObjectField(kInstanceClassNameOffset);
   VerifyObjectField(kFunctionDataOffset);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Fri Mar  7 09:10:18 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Fri Mar  7 10:12:17 2014 UTC
@@ -1474,7 +1474,7 @@
 AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
                                            ElementsKind to) {
   if (IsFastSmiElementsKind(from) &&
-      IsMoreGeneralElementsKindTransition(from, to)) {
+       IsMoreGeneralElementsKindTransition(from, to)) {
     return TRACK_ALLOCATION_SITE;
   }

@@ -4945,6 +4945,8 @@
 ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
                  kOptimizedCodeMapOffset)
 ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
+ACCESSORS(SharedFunctionInfo, feedback_vector, FixedArray,
+          kFeedbackVectorOffset)
 ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
 ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
           kInstanceClassNameOffset)
@@ -6622,10 +6624,6 @@
   int mask = (1 << kTypeChangeChecksumBits) - 1;
   return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
 }
-
-
-ACCESSORS(TypeFeedbackInfo, feedback_vector, FixedArray,
-          kFeedbackVectorOffset)


SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
=======================================
--- /branches/bleeding_edge/src/objects-printer.cc Fri Mar 7 08:43:54 2014 UTC +++ /branches/bleeding_edge/src/objects-printer.cc Fri Mar 7 10:12:17 2014 UTC
@@ -566,8 +566,6 @@
   HeapObject::PrintHeader(out, "TypeFeedbackInfo");
   PrintF(out, " - ic_total_count: %d, ic_with_type_info_count: %d\n",
          ic_total_count(), ic_with_type_info_count());
-  PrintF(out, " - feedback_vector: ");
-  feedback_vector()->FixedArrayPrint(out);
 }


@@ -878,6 +876,8 @@
   PrintF(out, "\n - length = %d", length());
   PrintF(out, "\n - optimized_code_map = ");
   optimized_code_map()->ShortPrint(out);
+  PrintF(out, "\n - feedback_vector = ");
+  feedback_vector()->FixedArrayPrint(out);
   PrintF(out, "\n");
 }

=======================================
--- /branches/bleeding_edge/src/objects-visiting-inl.h Wed Feb 19 14:03:48 2014 UTC +++ /branches/bleeding_edge/src/objects-visiting-inl.h Fri Mar 7 10:12:17 2014 UTC
@@ -426,9 +426,6 @@
     Map* map, HeapObject* object) {
   Heap* heap = map->GetHeap();
   Code* code = Code::cast(object);
-  if (FLAG_cleanup_code_caches_at_gc) {
-    code->ClearTypeFeedbackInfo(heap);
-  }
   if (FLAG_age_code && !Serializer::enabled()) {
     code->MakeOlder(heap->mark_compact_collector()->marking_parity());
   }
@@ -444,6 +441,9 @@
   if (shared->ic_age() != heap->global_ic_age()) {
     shared->ResetForNewContext(heap->global_ic_age());
   }
+  if (FLAG_cleanup_code_caches_at_gc) {
+    shared->ClearTypeFeedbackInfo(heap);
+  }
   if (FLAG_cache_optimized_code &&
       FLAG_flush_optimized_code_cache &&
       !shared->optimized_code_map()->IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/objects.cc      Fri Mar  7 10:01:00 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Fri Mar  7 10:12:17 2014 UTC
@@ -10642,19 +10642,16 @@
 }


-void Code::ClearTypeFeedbackInfo(Heap* heap) {
-  if (kind() != FUNCTION) return;
-  Object* raw_info = type_feedback_info();
-  if (raw_info->IsTypeFeedbackInfo()) {
-    FixedArray* feedback_vector =
-        TypeFeedbackInfo::cast(raw_info)->feedback_vector();
-    for (int i = 0; i < feedback_vector->length(); i++) {
-      Object* obj = feedback_vector->get(i);
-      if (!obj->IsAllocationSite()) {
- // TODO(mvstanton): Can't I avoid a write barrier for this sentinel?
-        feedback_vector->set(i,
- TypeFeedbackInfo::RawUninitializedSentinel(heap));
-      }
+void SharedFunctionInfo::ClearTypeFeedbackInfo(Heap* heap) {
+  FixedArray* vector = feedback_vector();
+  for (int i = 0; i < vector->length(); i++) {
+    Object* obj = vector->get(i);
+    if (!obj->IsAllocationSite()) {
+      // The assert verifies we can skip the write barrier.
+      ASSERT(heap->uninitialized_symbol() ==
+             TypeFeedbackInfo::RawUninitializedSentinel(heap));
+      vector->set(i, TypeFeedbackInfo::RawUninitializedSentinel(heap),
+                  SKIP_WRITE_BARRIER);
     }
   }
 }
=======================================
--- /branches/bleeding_edge/src/objects.h       Fri Mar  7 08:43:54 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Fri Mar  7 10:12:17 2014 UTC
@@ -5469,8 +5469,6 @@
   void ClearInlineCaches();
   void ClearInlineCaches(Kind kind);

-  void ClearTypeFeedbackInfo(Heap* heap);
-
   BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
   uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);

@@ -6666,6 +6664,8 @@
   // Removed a specific optimized code object from the optimized code map.
   void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);

+  void ClearTypeFeedbackInfo(Heap* heap);
+
   // Trims the optimized code map after entries have been removed.
   void TrimOptimizedCodeMap(int shrink_by);

@@ -6781,6 +6781,12 @@
   inline int construction_count();
   inline void set_construction_count(int value);

+ // [feedback_vector] - accumulates ast node feedback from full-codegen and
+  // (increasingly) from crankshafted code where sufficient feedback isn't
+  // available. Currently the field is duplicated in
+  // TypeFeedbackInfo::feedback_vector, but the allocation is done here.
+  DECL_ACCESSORS(feedback_vector, FixedArray)
+
// [initial_map]: initial map of the first function called as a constructor.
   // Saved for the duration of the tracking phase.
   // This is a weak link (GC resets it to undefined_value if no other live
@@ -7072,8 +7078,10 @@
   static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
   static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
   static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
-  static const int kInitialMapOffset =
+  static const int kFeedbackVectorOffset =
       kInferredNameOffset + kPointerSize;
+  static const int kInitialMapOffset =
+      kFeedbackVectorOffset + kPointerSize;
// ast_node_count is a Smi field. It could be grouped with another Smi field
   // into a PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
   static const int kAstNodeCountOffset =
@@ -8168,8 +8176,6 @@
   inline void set_inlined_type_change_checksum(int checksum);
   inline bool matches_inlined_type_change_checksum(int checksum);

-  DECL_ACCESSORS(feedback_vector, FixedArray)
-
   static inline TypeFeedbackInfo* cast(Object* obj);

   // Dispatched behavior.
@@ -8178,10 +8184,9 @@

   static const int kStorage1Offset = HeapObject::kHeaderSize;
   static const int kStorage2Offset = kStorage1Offset + kPointerSize;
-  static const int kFeedbackVectorOffset =
-      kStorage2Offset + kPointerSize;
-  static const int kSize = kFeedbackVectorOffset + kPointerSize;
+  static const int kSize = kStorage2Offset + kPointerSize;

+ // TODO(mvstanton): move these sentinel declarations to shared function info.
   // The object that indicates an uninitialized cache.
   static inline Handle<Object> UninitializedSentinel(Isolate* isolate);

@@ -8197,9 +8202,6 @@
   // garbage collection (e.g., for patching the cache).
   static inline Object* RawUninitializedSentinel(Heap* heap);

-  static const int kForInFastCaseMarker = 0;
-  static const int kForInSlowCaseMarker = 1;
-
  private:
   static const int kTypeChangeChecksumBits = 7;

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Fri Mar  7 10:01:00 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Fri Mar  7 10:12:17 2014 UTC
@@ -2942,6 +2942,7 @@
   // Set the code, scope info, formal parameter count, and the length
   // of the target shared function info.
   target_shared->ReplaceCode(source_shared->code());
+  target_shared->set_feedback_vector(source_shared->feedback_vector());
   target_shared->set_scope_info(source_shared->scope_info());
   target_shared->set_length(source_shared->length());
   target_shared->set_formal_parameter_count(
@@ -8488,10 +8489,10 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  function->shared()->ClearTypeFeedbackInfo(isolate->heap());
   Code* unoptimized = function->shared()->code();
   if (unoptimized->kind() == Code::FUNCTION) {
     unoptimized->ClearInlineCaches();
-    unoptimized->ClearTypeFeedbackInfo(isolate->heap());
   }
   return isolate->heap()->undefined_value();
 }
=======================================
--- /branches/bleeding_edge/src/type-info.cc    Fri Feb 28 10:01:27 2014 UTC
+++ /branches/bleeding_edge/src/type-info.cc    Fri Mar  7 10:12:17 2014 UTC
@@ -43,16 +43,12 @@


 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
+                                       Handle<FixedArray> feedback_vector,
                                        Handle<Context> native_context,
                                        Zone* zone)
     : native_context_(native_context),
-      zone_(zone) {
-  Object* raw_info = code->type_feedback_info();
-  if (raw_info->IsTypeFeedbackInfo()) {
- feedback_vector_ = Handle<FixedArray>(TypeFeedbackInfo::cast(raw_info)->
-                                          feedback_vector());
-  }
-
+      zone_(zone),
+      feedback_vector_(feedback_vector) {
   BuildDictionary(code);
   ASSERT(dictionary_->IsDictionary());
 }
@@ -132,9 +128,9 @@

 byte TypeFeedbackOracle::ForInType(int feedback_vector_slot) {
   Handle<Object> value = GetInfo(feedback_vector_slot);
-  return value->IsSmi() &&
-      Smi::cast(*value)->value() == TypeFeedbackInfo::kForInFastCaseMarker
-          ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
+  return value.is_identical_to(
+      TypeFeedbackInfo::UninitializedSentinel(isolate()))
+      ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
 }


=======================================
--- /branches/bleeding_edge/src/type-info.h     Mon Feb 10 21:38:17 2014 UTC
+++ /branches/bleeding_edge/src/type-info.h     Fri Mar  7 10:12:17 2014 UTC
@@ -44,6 +44,7 @@
 class TypeFeedbackOracle: public ZoneObject {
  public:
   TypeFeedbackOracle(Handle<Code> code,
+                     Handle<FixedArray> feedback_vector,
                      Handle<Context> native_context,
                      Zone* zone);

=======================================
--- /branches/bleeding_edge/src/typing.cc       Mon Feb 10 21:38:17 2014 UTC
+++ /branches/bleeding_edge/src/typing.cc       Fri Mar  7 10:12:17 2014 UTC
@@ -40,6 +40,7 @@
     : info_(info),
       oracle_(
           Handle<Code>(info->closure()->shared()->code()),
+          Handle<FixedArray>(info->closure()->shared()->feedback_vector()),
           Handle<Context>(info->closure()->context()->native_context()),
           info->zone()),
       store_(info->zone()) {
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Tue Mar 4 12:48:17 2014 UTC +++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Mar 7 10:12:17 2014 UTC
@@ -119,8 +119,6 @@
   handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);

-  InitializeFeedbackVector();
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -1127,15 +1125,10 @@
   Label non_proxy;
   __ bind(&fixed_array);

-  Handle<Object> feedback = Handle<Object>(
-      Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
-      isolate());
-  StoreFeedbackVectorSlot(slot, feedback);
-
// No need for a write barrier, we are storing a Smi in the feedback vector.
   __ Move(rbx, FeedbackVector());
   __ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot)),
-          Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker));
+          TypeFeedbackInfo::MegamorphicSentinel(isolate()));
   __ Move(rbx, Smi::FromInt(1));  // Smi indicates slow check
   __ movp(rcx, Operand(rsp, 0 * kPointerSize));  // Get enumerated object
   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
@@ -2649,9 +2642,6 @@
   // Record source position for debugger.
   SetSourcePosition(expr->position());

-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
   __ Move(rbx, FeedbackVector());
   __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot()));

@@ -2829,9 +2819,6 @@
   __ movp(rdi, Operand(rsp, arg_count * kPointerSize));

   // Record call targets in unoptimized code, but not in the snapshot.
-  Handle<Object> uninitialized =
-      TypeFeedbackInfo::UninitializedSentinel(isolate());
-  StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
   __ Move(rbx, FeedbackVector());
   __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot()));

=======================================
--- /branches/bleeding_edge/test/cctest/test-compiler.cc Fri Mar 7 08:43:54 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-compiler.cc Fri Mar 7 10:12:17 2014 UTC
@@ -310,6 +310,40 @@
     CHECK_EQ(i, f->GetScriptLineNumber());
   }
 }
+
+
+TEST(FeedbackVectorPreservedAcrossRecompiles) {
+  if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
+  i::FLAG_allow_natives_syntax = true;
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  // Make sure function f has a call that uses a type feedback slot.
+  CompileRun("function fun() {};"
+             "fun1 = fun;"
+             "function f(a) { a(); } f(fun1);");
+
+  Handle<JSFunction> f =
+      v8::Utils::OpenHandle(
+          *v8::Handle<v8::Function>::Cast(
+              CcTest::global()->Get(v8_str("f"))));
+
+  // We shouldn't have deoptimization support. We want to recompile and
+  // verify that our feedback vector preserves information.
+  CHECK(!f->shared()->has_deoptimization_support());
+  Handle<FixedArray> feedback_vector(f->shared()->feedback_vector());
+
+  // Verify that we gathered feedback.
+  CHECK_EQ(1, feedback_vector->length());
+  CHECK(feedback_vector->get(0)->IsJSFunction());
+
+  CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);");
+
+  // Verify that the feedback is still "gathered" despite a recompilation
+  // of the full code.
+  CHECK(f->shared()->has_deoptimization_support());
+  CHECK(f->shared()->feedback_vector()->get(0)->IsJSFunction());
+}


 // Test that optimized code for different closures is actually shared
=======================================
--- /branches/bleeding_edge/test/cctest/test-heap.cc Fri Mar 7 09:10:18 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-heap.cc Fri Mar 7 10:12:17 2014 UTC
@@ -2855,8 +2855,7 @@
           *v8::Handle<v8::Function>::Cast(
               CcTest::global()->Get(v8_str("f"))));

-  Handle<FixedArray> feedback_vector(TypeFeedbackInfo::cast(
-      f->shared()->code()->type_feedback_info())->feedback_vector());
+  Handle<FixedArray> feedback_vector(f->shared()->feedback_vector());

   CHECK_EQ(2, feedback_vector->length());
   CHECK(feedback_vector->get(0)->IsJSFunction());

--
--
v8-dev mailing list
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to