Optimized double-to-integer conversions in bit operations by using SSE3 instructions if available.

Optimized initialization sequences that store to multiple properties of the same object.

Changed the D8 debugger frontend to use JSON messages.

Force garbage collections when disposing contexts.

Align code objects at 32-byte boundaries.


git-svn-id: http://v8.googlecode.com/svn/trunk@1388 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index 72f427e..d088463 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -97,6 +97,7 @@
 int Heap::gc_count_ = 0;
 
 int Heap::always_allocate_scope_depth_ = 0;
+bool Heap::context_disposed_pending_ = false;
 
 #ifdef DEBUG
 bool Heap::allocation_allowed_ = true;
@@ -293,6 +294,20 @@
 }
 
 
+void Heap::CollectAllGarbageIfContextDisposed() {
+  if (context_disposed_pending_) {
+    StatsRateScope scope(&Counters::gc_context);
+    CollectAllGarbage();
+    context_disposed_pending_ = false;
+  }
+}
+
+
+void Heap::NotifyContextDisposed() {
+  context_disposed_pending_ = true;
+}
+
+
 bool Heap::CollectGarbage(int requested_size, AllocationSpace space) {
   // The VM is in the GC state until exiting this function.
   VMState state(GC);
@@ -419,11 +434,15 @@
   tracer->set_full_gc_count(mc_count_);
   LOG(ResourceEvent("markcompact", "begin"));
 
-  MarkCompactPrologue();
+  MarkCompactCollector::Prepare(tracer);
 
-  MarkCompactCollector::CollectGarbage(tracer);
+  bool is_compacting = MarkCompactCollector::IsCompacting();
 
-  MarkCompactEpilogue();
+  MarkCompactPrologue(is_compacting);
+
+  MarkCompactCollector::CollectGarbage();
+
+  MarkCompactEpilogue(is_compacting);
 
   LOG(ResourceEvent("markcompact", "end"));
 
@@ -432,21 +451,26 @@
   Shrink();
 
   Counters::objs_since_last_full.Set(0);
+  context_disposed_pending_ = false;
 }
 
 
-void Heap::MarkCompactPrologue() {
+void Heap::MarkCompactPrologue(bool is_compacting) {
+  // At any old GC clear the keyed lookup cache to enable collection of unused
+  // maps.
   ClearKeyedLookupCache();
+
   CompilationCache::MarkCompactPrologue();
   RegExpImpl::OldSpaceCollectionPrologue();
-  Top::MarkCompactPrologue();
-  ThreadManager::MarkCompactPrologue();
+
+  Top::MarkCompactPrologue(is_compacting);
+  ThreadManager::MarkCompactPrologue(is_compacting);
 }
 
 
-void Heap::MarkCompactEpilogue() {
-  Top::MarkCompactEpilogue();
-  ThreadManager::MarkCompactEpilogue();
+void Heap::MarkCompactEpilogue(bool is_compacting) {
+  Top::MarkCompactEpilogue(is_compacting);
+  ThreadManager::MarkCompactEpilogue(is_compacting);
 }
 
 
@@ -1601,12 +1625,13 @@
 Object* Heap::CreateCode(const CodeDesc& desc,
                          ScopeInfo<>* sinfo,
                          Code::Flags flags,
-                         Code** self_reference) {
+                         Handle<Object> self_reference) {
   // Compute size
   int body_size = RoundUp(desc.instr_size + desc.reloc_size, kObjectAlignment);
   int sinfo_size = 0;
   if (sinfo != NULL) sinfo_size = sinfo->Serialize(NULL);
   int obj_size = Code::SizeFor(body_size, sinfo_size);
+  ASSERT(IsAligned(obj_size, Code::kCodeAlignment));
   Object* result;
   if (obj_size > MaxHeapObjectSize()) {
     result = lo_space_->AllocateRawCode(obj_size);
@@ -1624,9 +1649,10 @@
   code->set_sinfo_size(sinfo_size);
   code->set_flags(flags);
   code->set_ic_flag(Code::IC_TARGET_IS_ADDRESS);
-  // Allow self references to created code object.
-  if (self_reference != NULL) {
-    *self_reference = code;
+  // Allow self references to created code object by patching the handle to
+  // point to the newly allocated Code object.
+  if (!self_reference.is_null()) {
+    *(self_reference.location()) = code;
   }
   // Migrate generated code.
   // The generated code can contain Object** values (typically from handles)