Fix for bug 351257: type feedback vector initialization issue.
authormvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Mar 2014 15:18:17 +0000 (15:18 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Mar 2014 15:18:17 +0000 (15:18 +0000)
The feedback vector is stored in the shared function info, and there
is an effort to reuse it when re-running full code generation as a
prelude to creating optimized code. However we shouldn't reuse the
vector for lazily compiled methods on first compile, as scoping analysis
can change the allocation of vector slots.

BUG=351257
LOG=N
R=danno@chromium.org, bmeuer@chromium.org

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

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

src/compiler.cc
test/cctest/test-compiler.cc

index 21f107a..97f8e6f 100644 (file)
@@ -141,13 +141,11 @@ void CompilationInfo::Initialize(Isolate* isolate,
   }
   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);
-    }
+  if (!shared_info().is_null() && shared_info()->is_compiled()) {
+    // We should initialize the CompilationInfo feedback vector from the
+    // passed in shared info, rather than creating a new one.
+    feedback_vector_ = Handle<FixedArray>(shared_info()->feedback_vector(),
+                                          isolate);
   }
 }
 
index 97638e7..079b286 100644 (file)
@@ -347,6 +347,43 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) {
 }
 
 
+TEST(FeedbackVectorRecreatedOnScopeChanges) {
+  if (i::FLAG_always_opt || !i::FLAG_lazy) return;
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  CompileRun("function builder() {"
+             "  call_target = function() { return 3; };"
+             "  return (function() {"
+             "    eval('');"
+             "    return function() {"
+             "      'use strict';"
+             "      call_target();"
+             "    }"
+             "  })();"
+             "}"
+             "morphing_call = builder();");
+
+  Handle<JSFunction> f =
+      v8::Utils::OpenHandle(
+          *v8::Handle<v8::Function>::Cast(
+              CcTest::global()->Get(v8_str("morphing_call"))));
+
+  // morphing_call should have one feedback vector slot for the call to
+  // call_target(), scoping analysis having been performed.
+  CHECK_EQ(1, f->shared()->feedback_vector()->length());
+  // And yet it's not compiled.
+  CHECK(!f->shared()->is_compiled());
+
+  CompileRun("morphing_call();");
+
+  // On scoping analysis after lazy compile, the call is now a global
+  // call which needs no feedback vector slot.
+  CHECK_EQ(0, f->shared()->feedback_vector()->length());
+  CHECK(f->shared()->is_compiled());
+}
+
+
 // Test that optimized code for different closures is actually shared
 // immediately by the FastNewClosureStub when run in the same context.
 TEST(OptimizedCodeSharing) {