- Pass the knowledge whether the old GC is compacting to the GC prologue and epilogue...
authoriposva@chromium.org <iposva@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 25 Feb 2009 16:52:15 +0000 (16:52 +0000)
committeriposva@chromium.org <iposva@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 25 Feb 2009 16:52:15 +0000 (16:52 +0000)
- Add the ability for the code to refer to its code object by adding a handle to the code object in the MacroAssembler.

Review URL: http://codereview.chromium.org/27133

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

33 files changed:
src/accessors.cc
src/builtins.cc
src/code-stubs.cc
src/codegen.cc
src/debug.cc
src/factory.cc
src/factory.h
src/frames-arm.cc
src/frames-ia32.cc
src/frames.cc
src/frames.h
src/heap.cc
src/heap.h
src/macro-assembler-arm.cc
src/macro-assembler-arm.h
src/macro-assembler-ia32.cc
src/macro-assembler-ia32.h
src/mark-compact.cc
src/mark-compact.h
src/regexp-macro-assembler-ia32.cc
src/regexp-macro-assembler-ia32.h
src/runtime.cc
src/spaces.cc
src/stub-cache.cc
src/stub-cache.h
src/top.cc
src/top.h
src/v8threads.cc
src/v8threads.h
test/cctest/test-assembler-arm.cc
test/cctest/test-assembler-ia32.cc
test/cctest/test-disasm-ia32.cc
test/cctest/test-heap.cc

index bbf60df..901dc07 100644 (file)
@@ -387,8 +387,8 @@ Object* Accessors::FunctionGetArguments(Object* object, void*) {
     if (frame->function() != *function) continue;
 
     // If there is an arguments variable in the stack, we return that.
-    int index = ScopeInfo<>::StackSlotIndex(frame->FindCode(),
-                                          Heap::arguments_symbol());
+    int index = ScopeInfo<>::StackSlotIndex(frame->code(),
+                                            Heap::arguments_symbol());
     if (index >= 0) return frame->GetExpression(index);
 
     // If there isn't an arguments variable in the stack, we need to
index c905489..c4991c3 100644 (file)
@@ -688,7 +688,7 @@ void Builtins::Setup(bool create_heap_objects) {
         // During startup it's OK to always allocate and defer GC to later.
         // This simplifies things because we don't need to retry.
         AlwaysAllocateScope __scope__;
-        code = Heap::CreateCode(desc, NULL, flags, NULL);
+        code = Heap::CreateCode(desc, NULL, flags, masm.CodeObject());
         if (code->IsFailure()) {
           v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
         }
index 2ead1b3..417806f 100644 (file)
@@ -59,7 +59,7 @@ Handle<Code> CodeStub::GetCode() {
 
     // Copy the generated code into a heap object, and store the major key.
     Code::Flags flags = Code::ComputeFlags(Code::STUB);
-    Handle<Code> code = Factory::NewCode(desc, NULL, flags);
+    Handle<Code> code = Factory::NewCode(desc, NULL, flags, masm.CodeObject());
     code->set_major_key(MajorKey());
 
     // Add unresolved entries in the code to the fixup list.
index 81c2af8..271f571 100644 (file)
@@ -130,7 +130,10 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* flit,
   cgen.masm()->GetCode(&desc);
   ScopeInfo<> sinfo(flit->scope());
   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
-  Handle<Code> code = Factory::NewCode(desc, &sinfo, flags);
+  Handle<Code> code = Factory::NewCode(desc,
+                                       &sinfo,
+                                       flags,
+                                       cgen.masm()->CodeObject());
 
   // Add unresolved entries in the code to the fixup list.
   Bootstrapper::AddFixup(*code, cgen.masm());
index dba09e2..f36bf2d 100644 (file)
@@ -1266,7 +1266,7 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
   Handle<Code> original_code(debug_info->original_code());
 #ifdef DEBUG
   // Get the code which is actually executing.
-  Handle<Code> frame_code(frame->FindCode());
+  Handle<Code> frame_code(frame->code());
   ASSERT(frame_code.is_identical_to(code));
 #endif
 
index 35d8c51..ec52520 100644 (file)
@@ -487,13 +487,7 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
 
 Handle<Code> Factory::NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
                               Code::Flags flags, Handle<Object> self_ref) {
-  CALL_HEAP_FUNCTION(Heap::CreateCode(
-      desc, sinfo, flags, reinterpret_cast<Code**>(self_ref.location())), Code);
-}
-
-Handle<Code> Factory::NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
-                              Code::Flags flags) {
-  CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags, NULL), Code);
+  CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags, self_ref), Code);
 }
 
 
index c5c3384..f282896 100644 (file)
@@ -206,9 +206,6 @@ class Factory : public AllStatic {
   static Handle<Code> NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
                               Code::Flags flags, Handle<Object> self_reference);
 
-  static Handle<Code> NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
-                              Code::Flags flags);
-
   static Handle<Code> CopyCode(Handle<Code> code);
 
   static Handle<Object> ToObject(Handle<Object> object,
index f7e7452..fe850a8 100644 (file)
@@ -114,10 +114,4 @@ Address InternalFrame::GetCallerStackPointer() const {
 }
 
 
-Code* JavaScriptFrame::FindCode() const {
-  JSFunction* function = JSFunction::cast(this->function());
-  return function->shared()->code();
-}
-
-
 } }  // namespace v8::internal
index ddf4bfd..2b24777 100644 (file)
@@ -112,10 +112,4 @@ Address InternalFrame::GetCallerStackPointer() const {
 }
 
 
-Code* JavaScriptFrame::FindCode() const {
-  JSFunction* function = JSFunction::cast(this->function());
-  return function->shared()->code();
-}
-
-
 } }  // namespace v8::internal
index 09c6a02..20a7149 100644 (file)
@@ -28,6 +28,7 @@
 #include "v8.h"
 
 #include "frames-inl.h"
+#include "mark-compact.h"
 #include "scopeinfo.h"
 #include "string-stream.h"
 #include "top.h"
@@ -162,12 +163,14 @@ void JavaScriptFrameIterator::Reset() {
 
 
 void StackHandler::Cook(Code* code) {
+  ASSERT(MarkCompactCollector::IsCompacting());
   ASSERT(code->contains(pc()));
   set_pc(AddressFrom<Address>(pc() - code->instruction_start()));
 }
 
 
 void StackHandler::Uncook(Code* code) {
+  ASSERT(MarkCompactCollector::IsCompacting());
   set_pc(code->instruction_start() + OffsetFrom(pc()));
   ASSERT(code->contains(pc()));
 }
@@ -183,6 +186,9 @@ bool StackFrame::HasHandler() const {
 
 
 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {
+  // Only cooking frames when the collector is compacting and thus moving code
+  // around.
+  ASSERT(MarkCompactCollector::IsCompacting());
   ASSERT(!thread->stack_is_cooked());
   for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
     it.frame()->Cook();
@@ -192,6 +198,9 @@ void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {
 
 
 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) {
+  // Only uncooking frames when the collector is compacting and thus moving code
+  // around.
+  ASSERT(MarkCompactCollector::IsCompacting());
   ASSERT(thread->stack_is_cooked());
   for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
     it.frame()->Uncook();
@@ -201,7 +210,7 @@ void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) {
 
 
 void StackFrame::Cook() {
-  Code* code = FindCode();
+  Code* code = this->code();
   for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
     it.handler()->Cook(code);
   }
@@ -211,7 +220,7 @@ void StackFrame::Cook() {
 
 
 void StackFrame::Uncook() {
-  Code* code = FindCode();
+  Code* code = this->code();
   for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
     it.handler()->Uncook(code);
   }
@@ -220,7 +229,7 @@ void StackFrame::Uncook() {
 }
 
 
-Code* EntryFrame::FindCode() const {
+Code* EntryFrame::code() const {
   return Heap::js_entry_code();
 }
 
@@ -232,12 +241,12 @@ StackFrame::Type EntryFrame::GetCallerState(State* state) const {
 }
 
 
-Code* EntryConstructFrame::FindCode() const {
+Code* EntryConstructFrame::code() const {
   return Heap::js_construct_entry_code();
 }
 
 
-Code* ExitFrame::FindCode() const {
+Code* ExitFrame::code() const {
   return Heap::c_entry_code();
 }
 
@@ -257,7 +266,7 @@ Address ExitFrame::GetCallerStackPointer() const {
 }
 
 
-Code* ExitDebugFrame::FindCode() const {
+Code* ExitDebugFrame::code() const {
   return Heap::c_entry_debug_break_code();
 }
 
@@ -320,20 +329,20 @@ bool JavaScriptFrame::IsConstructor() const {
 }
 
 
-Code* ArgumentsAdaptorFrame::FindCode() const {
+Code* JavaScriptFrame::code() const {
+  JSFunction* function = JSFunction::cast(this->function());
+  return function->shared()->code();
+}
+
+
+Code* ArgumentsAdaptorFrame::code() const {
   return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline);
 }
 
 
-Code* InternalFrame::FindCode() const {
+Code* InternalFrame::code() const {
   const int offset = InternalFrameConstants::kCodeOffset;
   Object* code = Memory::Object_at(fp() + offset);
-  if (code == NULL) {
-    // The code object isn't set; find it and set it.
-    code = Heap::FindCodeObject(pc());
-    ASSERT(!code->IsFailure());
-    Memory::Object_at(fp() + offset) = code;
-  }
   ASSERT(code != NULL);
   return Code::cast(code);
 }
index ea82cc6..c18cb74 100644 (file)
@@ -148,7 +148,7 @@ class StackFrame BASE_EMBEDDED {
   virtual Type type() const = 0;
 
   // Get the code associated with this frame.
-  virtual Code* FindCode() const = 0;
+  virtual Code* code() const = 0;
 
   // Garbage collection support.
   static void CookFramesForThread(ThreadLocalTop* thread);
@@ -209,7 +209,7 @@ class EntryFrame: public StackFrame {
  public:
   virtual Type type() const { return ENTRY; }
 
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   // Garbage collection support.
   virtual void Iterate(ObjectVisitor* v) const;
@@ -238,7 +238,7 @@ class EntryConstructFrame: public EntryFrame {
  public:
   virtual Type type() const { return ENTRY_CONSTRUCT; }
 
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   static EntryConstructFrame* cast(StackFrame* frame) {
     ASSERT(frame->is_entry_construct());
@@ -259,7 +259,7 @@ class ExitFrame: public StackFrame {
  public:
   virtual Type type() const { return EXIT; }
 
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   // Garbage collection support.
   virtual void Iterate(ObjectVisitor* v) const;
@@ -290,7 +290,7 @@ class ExitDebugFrame: public ExitFrame {
  public:
   virtual Type type() const { return EXIT_DEBUG; }
 
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   static ExitDebugFrame* cast(StackFrame* frame) {
     ASSERT(frame->is_exit_debug());
@@ -399,7 +399,7 @@ class JavaScriptFrame: public StandardFrame {
                      int index) const;
 
   // Determine the code for the frame.
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   static JavaScriptFrame* cast(StackFrame* frame) {
     ASSERT(frame->is_java_script());
@@ -433,7 +433,7 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame {
   virtual Type type() const { return ARGUMENTS_ADAPTOR; }
 
   // Determine the code for the frame.
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
     ASSERT(frame->is_arguments_adaptor());
@@ -463,7 +463,7 @@ class InternalFrame: public StandardFrame {
   virtual void Iterate(ObjectVisitor* v) const;
 
   // Determine the code for the frame.
-  virtual Code* FindCode() const;
+  virtual Code* code() const;
 
   static InternalFrame* cast(StackFrame* frame) {
     ASSERT(frame->is_internal());
index 72f427e..d3651b9 100644 (file)
@@ -419,11 +419,15 @@ void Heap::MarkCompact(GCTracer* tracer) {
   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"));
 
@@ -435,18 +439,22 @@ void Heap::MarkCompact(GCTracer* tracer) {
 }
 
 
-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,7 +1609,7 @@ void Heap::CreateFillerObjectAt(Address addr, int size) {
 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;
@@ -1624,9 +1632,10 @@ Object* Heap::CreateCode(const CodeDesc& desc,
   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)
index f1cb8ee..b3cd4d2 100644 (file)
@@ -567,7 +567,7 @@ class Heap : public AllStatic {
   static Object* CreateCode(const CodeDesc& desc,
                             ScopeInfo<>* sinfo,
                             Code::Flags flags,
-                            Code** self_reference = NULL);
+                            Handle<Object> self_reference);
 
   static Object* CopyCode(Code* code);
   // Finds the symbol for string in the symbol table.
@@ -923,8 +923,8 @@ class Heap : public AllStatic {
   static void MarkCompact(GCTracer* tracer);
 
   // Code to be run before and after mark-compact.
-  static void MarkCompactPrologue();
-  static void MarkCompactEpilogue();
+  static void MarkCompactPrologue(bool is_compacting);
+  static void MarkCompactEpilogue(bool is_compacting);
 
   // Helper function used by CopyObject to copy a source object to an
   // allocated target object and update the forwarding pointer in the source
index dc6d40f..88a300b 100644 (file)
@@ -43,7 +43,8 @@ MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
       unresolved_(0),
       generating_stub_(false),
-      allow_stub_calls_(true) {
+      allow_stub_calls_(true),
+      code_object_(Heap::undefined_value()) {
 }
 
 
@@ -270,8 +271,8 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
   stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
   mov(ip, Operand(Smi::FromInt(type)));
   push(ip);
-  mov(ip, Operand(0));
-  push(ip);  // Push an empty code cache slot.
+  mov(ip, Operand(CodeObject()));
+  push(ip);
   add(fp, sp, Operand(3 * kPointerSize));  // Adjust FP to point to saved FP.
 }
 
index b2edf3e..4b999fd 100644 (file)
@@ -230,6 +230,8 @@ class MacroAssembler: public Assembler {
   };
   List<Unresolved>* unresolved() { return &unresolved_; }
 
+  Handle<Object> CodeObject() { return code_object_; }
+
 
   // ---------------------------------------------------------------------------
   // StatsCounter support
@@ -265,6 +267,8 @@ class MacroAssembler: public Assembler {
   List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
+  Handle<Object> code_object_;  // This handle will be patched with the code
+                                // object on installation.
 
   // Helper functions for generating invokes.
   void InvokePrologue(const ParameterCount& expected,
index 80e4d3e..506f890 100644 (file)
@@ -39,7 +39,8 @@ MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
       unresolved_(0),
       generating_stub_(false),
-      allow_stub_calls_(true) {
+      allow_stub_calls_(true),
+      code_object_(Heap::undefined_value()) {
 }
 
 
@@ -317,7 +318,11 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
   mov(ebp, Operand(esp));
   push(esi);
   push(Immediate(Smi::FromInt(type)));
-  push(Immediate(0));  // Push an empty code cache slot.
+  push(Immediate(CodeObject()));
+  if (FLAG_debug_code) {
+    cmp(Operand(esp, 0), Immediate(Factory::undefined_value()));
+    Check(not_equal, "code object not properly patched");
+  }
 }
 
 
index b8fb3b9..b389df2 100644 (file)
@@ -235,6 +235,8 @@ class MacroAssembler: public Assembler {
   };
   List<Unresolved>* unresolved() { return &unresolved_; }
 
+  Handle<Object> CodeObject() { return code_object_; }
+
 
   // ---------------------------------------------------------------------------
   // StatsCounter support
@@ -267,6 +269,8 @@ class MacroAssembler: public Assembler {
   List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
+  Handle<Object> code_object_;  // This handle will be patched with the code
+                                // code object on installation.
 
   // Helper functions for generating invokes.
   void InvokePrologue(const ParameterCount& expected,
index 4ab4cfe..a747ca3 100644 (file)
@@ -58,11 +58,11 @@ int MarkCompactCollector::live_map_objects_ = 0;
 int MarkCompactCollector::live_lo_objects_ = 0;
 #endif
 
-void MarkCompactCollector::CollectGarbage(GCTracer* tracer) {
-  // Rather than passing the tracer around we stash it in a static member
-  // variable.
-  tracer_ = tracer;
-  Prepare();
+void MarkCompactCollector::CollectGarbage() {
+  // Make sure that Prepare() has been called. The individual steps below will
+  // update the state as they proceed.
+  ASSERT(state_ == PREPARE_GC);
+
   // Prepare has selected whether to compact the old generation or not.
   // Tell the tracer.
   if (IsCompacting()) tracer_->set_is_compacting();
@@ -96,7 +96,11 @@ void MarkCompactCollector::CollectGarbage(GCTracer* tracer) {
 }
 
 
-void MarkCompactCollector::Prepare() {
+void MarkCompactCollector::Prepare(GCTracer* tracer) {
+  // Rather than passing the tracer around we stash it in a static member
+  // variable.
+  tracer_ = tracer;
+
   static const int kFragmentationLimit = 50;  // Percent.
 #ifdef DEBUG
   ASSERT(state_ == IDLE);
@@ -241,7 +245,6 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
 // Helper class for marking pointers in HeapObjects.
 class MarkingVisitor : public ObjectVisitor {
  public:
-
   void VisitPointer(Object** p) {
     MarkObjectByPointer(p);
   }
index 746aead..9a92ade 100644 (file)
@@ -74,8 +74,12 @@ class MarkCompactCollector: public AllStatic {
   // Type of functions to process non-live objects.
   typedef void (*ProcessNonLiveFunction)(HeapObject* object);
 
+  // Prepares for GC by resetting relocation info in old and map spaces and
+  // choosing spaces to compact.
+  static void Prepare(GCTracer* tracer);
+
   // Performs a global garbage collection.
-  static void CollectGarbage(GCTracer* tracer);
+  static void CollectGarbage();
 
   // True if the last full GC performed heap compaction.
   static bool HasCompacted() { return compacting_collection_; }
@@ -123,10 +127,6 @@ class MarkCompactCollector: public AllStatic {
   // collection (NULL before and after).
   static GCTracer* tracer_;
 
-  // Prepares for GC by resetting relocation info in old and map spaces and
-  // choosing spaces to compact.
-  static void Prepare();
-
   // Finishes GC, performs heap verification if enabled.
   static void Finish();
 
index 0e96b9d..3483460 100644 (file)
@@ -99,8 +99,7 @@ RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
       start_label_(),
       success_label_(),
       backtrack_label_(),
-      exit_label_(),
-      self_(Heap::undefined_value()) {
+      exit_label_() {
   __ jmp(&entry_label_);   // We'll write the entry code later.
   __ bind(&start_label_);  // And then continue from here.
 }
@@ -145,7 +144,7 @@ void RegExpMacroAssemblerIA32::Backtrack() {
   CheckPreemption();
   // Pop Code* offset from backtrack stack, add Code* and jump to location.
   Pop(ebx);
-  __ add(Operand(ebx), Immediate(self_));
+  __ add(Operand(ebx), Immediate(masm_->CodeObject()));
   __ jmp(Operand(ebx));
 }
 
@@ -661,7 +660,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
   __ bind(&stack_limit_hit);
   int num_arguments = 2;
   FrameAlign(num_arguments, ebx);
-  __ mov(Operand(esp, 1 * kPointerSize), Immediate(self_));
+  __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject()));
   __ lea(eax, Operand(esp, -kPointerSize));
   __ mov(Operand(esp, 0 * kPointerSize), eax);
   CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
@@ -784,7 +783,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
     __ bind(&retry);
     int num_arguments = 2;
     FrameAlign(num_arguments, ebx);
-    __ mov(Operand(esp, 1 * kPointerSize), Immediate(self_));
+    __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject()));
     __ lea(eax, Operand(esp, -kPointerSize));
     __ mov(Operand(esp, 0 * kPointerSize), eax);
     CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
@@ -849,7 +848,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
   Handle<Code> code = Factory::NewCode(code_desc,
                                        NULL,
                                        Code::ComputeFlags(Code::REGEXP),
-                                       self_);
+                                       masm_->CodeObject());
   LOG(CodeCreateEvent("RegExp", *code, *(source->ToCString())));
   return Handle<Object>::cast(code);
 }
@@ -1139,7 +1138,7 @@ void RegExpMacroAssemblerIA32::SafeCall(Label* to) {
 
 void RegExpMacroAssemblerIA32::SafeReturn() {
   __ pop(ebx);
-  __ add(Operand(ebx), Immediate(self_));
+  __ add(Operand(ebx), Immediate(masm_->CodeObject()));
   __ jmp(Operand(ebx));
 }
 
index a9297f5..d6f11ad 100644 (file)
@@ -253,9 +253,6 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
   Label exit_label_;
   Label check_preempt_label_;
   Label stack_overflow_label_;
-
-  // Handle used to represent the generated code object itself.
-  Handle<Object> self_;
 };
 
 }}  // namespace v8::internal
index b687057..ea27da9 100644 (file)
@@ -5015,13 +5015,13 @@ static Object* Runtime_GetFrameDetails(Arguments args) {
   Handle<Object> frame_id(WrapFrameId(it.frame()->id()));
 
   // Find source position.
-  int position = it.frame()->FindCode()->SourcePosition(it.frame()->pc());
+  int position = it.frame()->code()->SourcePosition(it.frame()->pc());
 
   // Check for constructor frame.
   bool constructor = it.frame()->IsConstructor();
 
   // Get code and read scope info from it for local variable information.
-  Handle<Code> code(it.frame()->FindCode());
+  Handle<Code> code(it.frame()->code());
   ScopeInfo<> info(*code);
 
   // Get the context.
index 63add7c..b10139e 100644 (file)
@@ -538,11 +538,9 @@ void PagedSpace::ClearRSet() {
 
 
 Object* PagedSpace::FindObject(Address addr) {
-#ifdef DEBUG
   // Note: this function can only be called before or after mark-compact GC
   // because it accesses map pointers.
   ASSERT(!MarkCompactCollector::in_use());
-#endif
 
   if (!Contains(addr)) return Failure::Exception();
 
index 3daf357..35b5be3 100644 (file)
@@ -892,7 +892,7 @@ Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags) {
   CodeDesc desc;
   masm_.GetCode(&desc);
-  Object* result = Heap::CreateCode(desc, NULL, flags, NULL);
+  Object* result = Heap::CreateCode(desc, NULL, flags, masm_.CodeObject());
 #ifdef DEBUG
   if (FLAG_print_code_stubs && !result->IsFailure()) {
     Code::cast(result)->Print();
index 498a695..ec93c80 100644 (file)
@@ -281,7 +281,7 @@ class StubCompiler BASE_EMBEDDED {
     JSARRAY_HAS_FAST_ELEMENTS_CHECK
   };
 
-  StubCompiler() : masm_(NULL, 256) { }
+  StubCompiler() : scope_(), masm_(NULL, 256) { }
 
   Object* CompileCallInitialize(Code::Flags flags);
   Object* CompileCallPreMonomorphic(Code::Flags flags);
@@ -367,6 +367,7 @@ class StubCompiler BASE_EMBEDDED {
   MacroAssembler* masm() { return &masm_; }
 
  private:
+  HandleScope scope_;
   MacroAssembler masm_;
 };
 
index a35d266..aa0c58e 100644 (file)
@@ -333,33 +333,37 @@ int Top::break_id() {
 }
 
 
-void Top::MarkCompactPrologue() {
-  MarkCompactPrologue(&thread_local_);
+void Top::MarkCompactPrologue(bool is_compacting) {
+  MarkCompactPrologue(is_compacting, &thread_local_);
 }
 
 
-void Top::MarkCompactPrologue(char* data) {
-  MarkCompactPrologue(reinterpret_cast<ThreadLocalTop*>(data));
+void Top::MarkCompactPrologue(bool is_compacting, char* data) {
+  MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
 }
 
 
-void Top::MarkCompactPrologue(ThreadLocalTop* thread) {
-  StackFrame::CookFramesForThread(thread);
+void Top::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) {
+  if (is_compacting) {
+    StackFrame::CookFramesForThread(thread);
+  }
 }
 
 
-void Top::MarkCompactEpilogue(char* data) {
-  MarkCompactEpilogue(reinterpret_cast<ThreadLocalTop*>(data));
+void Top::MarkCompactEpilogue(bool is_compacting, char* data) {
+  MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
 }
 
 
-void Top::MarkCompactEpilogue() {
-  MarkCompactEpilogue(&thread_local_);
+void Top::MarkCompactEpilogue(bool is_compacting) {
+  MarkCompactEpilogue(is_compacting, &thread_local_);
 }
 
 
-void Top::MarkCompactEpilogue(ThreadLocalTop* thread) {
-  StackFrame::UncookFramesForThread(thread);
+void Top::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) {
+  if (is_compacting) {
+    StackFrame::UncookFramesForThread(thread);
+  }
 }
 
 
@@ -690,7 +694,7 @@ void Top::PrintCurrentStackTrace(FILE* out) {
     HandleScope scope;
     // Find code position if recorded in relocation info.
     JavaScriptFrame* frame = it.frame();
-    int pos = frame->FindCode()->SourcePosition(frame->pc());
+    int pos = frame->code()->SourcePosition(frame->pc());
     Handle<Object> pos_obj(Smi::FromInt(pos));
     // Fetch function and receiver.
     Handle<JSFunction> fun(JSFunction::cast(frame->function()));
@@ -721,7 +725,7 @@ void Top::ComputeLocation(MessageLocation* target) {
     Object* script = fun->shared()->script();
     if (script->IsScript() &&
         !(Script::cast(script)->source()->IsUndefined())) {
-      int pos = frame->FindCode()->SourcePosition(frame->pc());
+      int pos = frame->code()->SourcePosition(frame->pc());
       // Compute the location from the function and the reloc info.
       Handle<Script> casted_script(Script::cast(script));
       *target = MessageLocation(casted_script, pos, pos + 1);
index 0a3bec3..26151bd 100644 (file)
--- a/src/top.h
+++ b/src/top.h
@@ -189,10 +189,12 @@ class Top {
   static StackFrame::Id break_frame_id();
   static int break_id();
 
-  static void MarkCompactPrologue();
-  static void MarkCompactEpilogue();
-  static void MarkCompactPrologue(char* archived_thread_data);
-  static void MarkCompactEpilogue(char* archived_thread_data);
+  static void MarkCompactPrologue(bool is_compacting);
+  static void MarkCompactEpilogue(bool is_compacting);
+  static void MarkCompactPrologue(bool is_compacting,
+                                  char* archived_thread_data);
+  static void MarkCompactEpilogue(bool is_compacting,
+                                  char* archived_thread_data);
   static void PrintCurrentStackTrace(FILE* out);
   static void PrintStackTrace(FILE* out, char* thread_data);
   static void PrintStack(StringStream* accumulator);
@@ -293,8 +295,10 @@ class Top {
   static ThreadLocalTop thread_local_;
   static void InitializeThreadLocal();
   static void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
-  static void MarkCompactPrologue(ThreadLocalTop* archived_thread_data);
-  static void MarkCompactEpilogue(ThreadLocalTop* archived_thread_data);
+  static void MarkCompactPrologue(bool is_compacting,
+                                  ThreadLocalTop* archived_thread_data);
+  static void MarkCompactEpilogue(bool is_compacting,
+                                  ThreadLocalTop* archived_thread_data);
 
   // Debug.
   // Mutex for serializing access to break control structures.
index df0095d..f4a7f72 100644 (file)
@@ -268,24 +268,24 @@ void ThreadManager::Iterate(ObjectVisitor* v) {
 }
 
 
-void ThreadManager::MarkCompactPrologue() {
+void ThreadManager::MarkCompactPrologue(bool is_compacting) {
   for (ThreadState* state = ThreadState::FirstInUse();
        state != NULL;
        state = state->Next()) {
     char* data = state->data();
     data += HandleScopeImplementer::ArchiveSpacePerThread();
-    Top::MarkCompactPrologue(data);
+    Top::MarkCompactPrologue(is_compacting, data);
   }
 }
 
 
-void ThreadManager::MarkCompactEpilogue() {
+void ThreadManager::MarkCompactEpilogue(bool is_compacting) {
   for (ThreadState* state = ThreadState::FirstInUse();
        state != NULL;
        state = state->Next()) {
     char* data = state->data();
     data += HandleScopeImplementer::ArchiveSpacePerThread();
-    Top::MarkCompactEpilogue(data);
+    Top::MarkCompactEpilogue(is_compacting, data);
   }
 }
 
index b86df73..35db9ad 100644 (file)
@@ -74,8 +74,8 @@ class ThreadManager : public AllStatic {
   static bool RestoreThread();
 
   static void Iterate(ObjectVisitor* v);
-  static void MarkCompactPrologue();
-  static void MarkCompactEpilogue();
+  static void MarkCompactPrologue(bool is_compacting);
+  static void MarkCompactEpilogue(bool is_compacting);
   static bool IsLockedByCurrentThread() { return mutex_owner_.IsSelf(); }
  private:
   static void EagerlyArchiveThread();
index f8a952c..bd75a04 100644 (file)
@@ -72,7 +72,10 @@ TEST(0) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -106,7 +109,10 @@ TEST(1) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -149,7 +155,10 @@ TEST(2) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -194,7 +203,10 @@ TEST(3) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
index fac4a6f..9ad7c76 100644 (file)
@@ -69,7 +69,10 @@ TEST(AssemblerIa320) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -104,7 +107,10 @@ TEST(AssemblerIa321) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -143,7 +149,10 @@ TEST(AssemblerIa322) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -173,7 +182,10 @@ TEST(AssemblerIa323) {
   CodeDesc desc;
   assm.GetCode(&desc);
   Code* code =
-      Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
+      Code::cast(Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value())));
   // don't print the code - our disassembler can't handle cvttss2si
   // instead print bytes
   Disassembler::Dump(stdout,
@@ -203,7 +215,10 @@ TEST(AssemblerIa324) {
   CodeDesc desc;
   assm.GetCode(&desc);
   Code* code =
-      Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
+      Code::cast(Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value())));
   // don't print the code - our disassembler can't handle cvttsd2si
   // instead print bytes
   Disassembler::Dump(stdout,
@@ -230,7 +245,10 @@ TEST(AssemblerIa325) {
   CodeDesc desc;
   assm.GetCode(&desc);
   Code* code =
-      Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
+      Code::cast(Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value())));
   F0 f = FUNCTION_CAST<F0>(code->entry());
   int res = f();
   CHECK_EQ(42, res);
@@ -263,7 +281,10 @@ TEST(AssemblerIa326) {
   CodeDesc desc;
   assm.GetCode(&desc);
   Code* code =
-      Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
+      Code::cast(Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value())));
 #ifdef DEBUG
   ::printf("\n---\n");
   // don't print the code - our disassembler can't handle SSE instructions
@@ -299,7 +320,10 @@ TEST(AssemblerIa328) {
   CodeDesc desc;
   assm.GetCode(&desc);
   Code* code =
-      Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
+      Code::cast(Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value())));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
@@ -352,7 +376,10 @@ TEST(AssemblerIa329) {
   CodeDesc desc;
   assm.GetCode(&desc);
   Code* code =
-      Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
+      Code::cast(Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value())));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
index a974905..af9fb97 100644 (file)
@@ -368,7 +368,10 @@ TEST(DisasmIa320) {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 #ifdef DEBUG
   Code::cast(code)->Print();
index 4ac1ae4..a146c4c 100644 (file)
@@ -77,7 +77,10 @@ static void CheckFindCodeObject() {
 
   CodeDesc desc;
   assm.GetCode(&desc);
-  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* code = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(code->IsCode());
 
   HeapObject* obj = HeapObject::cast(code);
@@ -88,7 +91,10 @@ static void CheckFindCodeObject() {
     CHECK_EQ(code, found);
   }
 
-  Object* copy = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
+  Object* copy = Heap::CreateCode(desc,
+                                  NULL,
+                                  Code::ComputeFlags(Code::STUB),
+                                  Handle<Object>(Heap::undefined_value()));
   CHECK(copy->IsCode());
   HeapObject* obj_copy = HeapObject::cast(copy);
   Object* not_right = Heap::FindCodeObject(obj_copy->address() +