Revision: 3482
Author: [email protected]
Date: Thu Dec 17 00:53:19 2009
Log: Enable fast allocation of context objects on IA-32.
Review URL: http://codereview.chromium.org/507035
http://code.google.com/p/v8/source/detail?r=3482

Modified:
  /branches/bleeding_edge/src/code-stubs.h
  /branches/bleeding_edge/src/codegen.h
  /branches/bleeding_edge/src/ia32/codegen-ia32.cc

=======================================
--- /branches/bleeding_edge/src/code-stubs.h    Wed Dec 16 07:43:20 2009
+++ /branches/bleeding_edge/src/code-stubs.h    Thu Dec 17 00:53:19 2009
@@ -44,6 +44,7 @@
    V(WriteInt32ToHeapNumber)              \
    V(StackCheck)                          \
    V(FastNewClosure)                      \
+  V(FastNewContext)                      \
    V(UnarySub)                            \
    V(RevertToNumber)                      \
    V(ToBoolean)                           \
=======================================
--- /branches/bleeding_edge/src/codegen.h       Wed Dec 16 07:43:20 2009
+++ /branches/bleeding_edge/src/codegen.h       Thu Dec 17 00:53:19 2009
@@ -244,6 +244,25 @@
  };


+class FastNewContextStub : public CodeStub {
+ public:
+  static const int kMaximumSlots = 64;
+
+  explicit FastNewContextStub(int slots) : slots_(slots) {
+    ASSERT(slots_ > 0 && slots <= kMaximumSlots);
+  }
+
+  void Generate(MacroAssembler* masm);
+
+ private:
+  int slots_;
+
+  const char* GetName() { return "FastNewContextStub"; }
+  Major MajorKey() { return FastNewContext; }
+  int MinorKey() { return slots_; }
+};
+
+
  class InstanceofStub: public CodeStub {
   public:
    InstanceofStub() { }
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Wed Dec 16 23:35:12  
2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Thu Dec 17 00:53:19  
2009
@@ -174,12 +174,19 @@
      function_return_is_shadowed_ = false;

      // Allocate the local context if needed.
-    if (scope_->num_heap_slots() > 0) {
+    int heap_slots = scope_->num_heap_slots();
+    if (heap_slots > 0) {
        Comment cmnt(masm_, "[ allocate local context");
        // Allocate local context.
        // Get outer context and create a new context based on it.
        frame_->PushFunction();
-      Result context = frame_->CallRuntime(Runtime::kNewContext, 1);
+      Result context;
+      if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+        FastNewContextStub stub(heap_slots);
+        context = frame_->CallStub(&stub, 1);
+      } else {
+        context = frame_->CallRuntime(Runtime::kNewContext, 1);
+      }

        // Update context local.
        frame_->SaveContextRegister();
@@ -6588,6 +6595,47 @@
    __ push(ecx);  // Restore return address.
    __ TailCallRuntime(ExternalReference(Runtime::kNewClosure), 2, 1);
  }
+
+
+void FastNewContextStub::Generate(MacroAssembler* masm) {
+  // Try to allocate the context in new space.
+  Label gc;
+  int length = slots_ + Context::MIN_CONTEXT_SLOTS;
+  __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
+                        eax, ebx, ecx, &gc, TAG_OBJECT);
+
+  // Get the function from the stack.
+  __ mov(ecx, Operand(esp, 1 * kPointerSize));
+
+  // Setup the object header.
+  __ mov(FieldOperand(eax, HeapObject::kMapOffset),  
Factory::context_map());
+  __ mov(FieldOperand(eax, Array::kLengthOffset), Immediate(length));
+
+  // Setup the fixed slots.
+  __ xor_(ebx, Operand(ebx));  // Set to NULL.
+  __ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx);
+  __ mov(Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)), eax);
+  __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), ebx);
+  __ mov(Operand(eax, Context::SlotOffset(Context::EXTENSION_INDEX)), ebx);
+
+  // Copy the global object from the surrounding context.
+  __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
+
+  // Initialize the rest of the slots to undefined.
+  __ mov(ebx, Factory::undefined_value());
+  for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
+    __ mov(Operand(eax, Context::SlotOffset(i)), ebx);
+  }
+
+  // Return and remove the on-stack parameter.
+  __ mov(esi, Operand(eax));
+  __ ret(1 * kPointerSize);
+
+  // Need to collect. Call into runtime system.
+  __ bind(&gc);
+  __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1);
+}


  // NOTE: The stub does not handle the inlined cases (Smis, Booleans,  
undefined).

-- 
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to