Enable weak embedded maps in optimized code.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 2 Jul 2013 15:15:58 +0000 (15:15 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 2 Jul 2013 15:15:58 +0000 (15:15 +0000)
If the top optimized code in call stack is at the point that does not support
deoptimization, then treat the maps in the code as strong pointers.

Note that other optimized code in call stack must support deoptimization
because of the call instruction with side-effects.

BUG=217858,v8:2073
R=mstarzinger@chromium.org

Review URL: https://chromiumcodereview.appspot.com/16955008

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

src/flag-definitions.h
src/mark-compact.cc
src/mark-compact.h
src/objects.cc
src/objects.h
test/mjsunit/regress/regress-crbug-217858.js

index b07354a..c990ed1 100644 (file)
@@ -469,7 +469,7 @@ DEFINE_bool(trace_external_memory, false,
             "it is adjusted.")
 DEFINE_bool(collect_maps, true,
             "garbage collect maps from which no objects can be reached")
-DEFINE_bool(weak_embedded_maps_in_optimized_code, false,
+DEFINE_bool(weak_embedded_maps_in_optimized_code, true,
             "make maps embedded in optimized code weak")
 DEFINE_bool(flush_code, true,
             "flush code that we expect not to use again (during full gc)")
index 3940b56..449e655 100644 (file)
@@ -2181,6 +2181,32 @@ void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) {
 }
 
 
+static StackFrame* TopOptimizedFrame(Isolate* isolate) {
+  for (StackFrameIterator it(isolate, isolate->thread_local_top());
+       !it.done(); it.Advance()) {
+    if (it.frame()->type() == StackFrame::JAVA_SCRIPT) {
+      return NULL;
+    }
+    if (it.frame()->type() == StackFrame::OPTIMIZED) {
+      return it.frame();
+    }
+  }
+  return NULL;
+}
+
+
+void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
+  StackFrame* frame = TopOptimizedFrame(isolate());
+  if (frame != NULL) {
+    Code* code = frame->LookupCode();
+    if (!code->CanDeoptAt(frame->pc())) {
+      code->CodeIterateBody(visitor);
+    }
+    ProcessMarkingDeque();
+  }
+}
+
+
 void MarkCompactCollector::MarkLiveObjects() {
   GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
   // The recursive GC marker detects when it is nearing stack overflow,
@@ -2260,6 +2286,8 @@ void MarkCompactCollector::MarkLiveObjects() {
   RootMarkingVisitor root_visitor(heap());
   MarkRoots(&root_visitor);
 
+  ProcessTopOptimizedFrame(&root_visitor);
+
   // The objects reachable from the roots are marked, yet unreachable
   // objects are unmarked.  Mark objects reachable due to host
   // application specific logic or through Harmony weak maps.
index db188ed..ab3711a 100644 (file)
@@ -853,6 +853,11 @@ class MarkCompactCollector {
   //      or implicit references' groups.
   void ProcessEphemeralMarking(ObjectVisitor* visitor);
 
+  // If the call-site of the top optimized code was not prepared for
+  // deoptimization, then treat the maps in the code as strong pointers,
+  // otherwise a map can die and deoptimize the code.
+  void ProcessTopOptimizedFrame(ObjectVisitor* visitor);
+
   // Mark objects reachable (transitively) from objects in the marking
   // stack.  This function empties the marking stack, but may leave
   // overflowed objects in the heap, in which case the marking stack's
index d1a617e..7d98a8a 100644 (file)
@@ -10385,6 +10385,19 @@ void Code::PrintDeoptLocation(int bailout_id) {
 }
 
 
+bool Code::CanDeoptAt(Address pc) {
+  DeoptimizationInputData* deopt_data =
+      DeoptimizationInputData::cast(deoptimization_data());
+  Address code_start_address = instruction_start();
+  for (int i = 0; i < deopt_data->DeoptCount(); i++) {
+    if (deopt_data->Pc(i)->value() == -1) continue;
+    Address address = code_start_address + deopt_data->Pc(i)->value();
+    if (address == pc) return true;
+  }
+  return false;
+}
+
+
 // Identify kind of code.
 const char* Code::Kind2String(Kind kind) {
   switch (kind) {
index adaa9cf..45f9816 100644 (file)
@@ -4841,6 +4841,7 @@ class Code: public HeapObject {
   int GetAge();
 
   void PrintDeoptLocation(int bailout_id);
+  bool CanDeoptAt(Address pc);
 
 #ifdef VERIFY_HEAP
   void VerifyEmbeddedMapsDependency();
index 8563e07..e61cb9f 100644 (file)
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax
+// Flags: --noanalyze_environment_liveness
 
 var r = /r/;
-var a = "";
 function f() {
-  %OptimizeFunctionOnNextCall(f, "osr");
-  for (var i = 0; i < 1000000; i++) {
-    a += i.toString();
-    r[r] = function() {};
-  }
+  r[r] = function() {};
 }
 
-f();
+for (var i = 0; i < 300000; i++) {
+  f();
+}