Commit f4251cc4 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Enable fast allocation of context objects on IA-32.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3482 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 44b7c59e
...@@ -44,6 +44,7 @@ namespace internal { ...@@ -44,6 +44,7 @@ namespace internal {
V(WriteInt32ToHeapNumber) \ V(WriteInt32ToHeapNumber) \
V(StackCheck) \ V(StackCheck) \
V(FastNewClosure) \ V(FastNewClosure) \
V(FastNewContext) \
V(UnarySub) \ V(UnarySub) \
V(RevertToNumber) \ V(RevertToNumber) \
V(ToBoolean) \ V(ToBoolean) \
......
...@@ -244,6 +244,25 @@ class FastNewClosureStub : public CodeStub { ...@@ -244,6 +244,25 @@ class FastNewClosureStub : public CodeStub {
}; };
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 { class InstanceofStub: public CodeStub {
public: public:
InstanceofStub() { } InstanceofStub() { }
......
...@@ -174,12 +174,19 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { ...@@ -174,12 +174,19 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) {
function_return_is_shadowed_ = false; function_return_is_shadowed_ = false;
// Allocate the local context if needed. // 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"); Comment cmnt(masm_, "[ allocate local context");
// Allocate local context. // Allocate local context.
// Get outer context and create a new context based on it. // Get outer context and create a new context based on it.
frame_->PushFunction(); 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. // Update context local.
frame_->SaveContextRegister(); frame_->SaveContextRegister();
...@@ -6590,6 +6597,47 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) { ...@@ -6590,6 +6597,47 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
} }
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). // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined).
void ToBooleanStub::Generate(MacroAssembler* masm) { void ToBooleanStub::Generate(MacroAssembler* masm) {
Label false_result, true_result, not_string; Label false_result, true_result, not_string;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment