| Index: be2/src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- be2/src/ia32/codegen-ia32.cc (revision 3480)
|
| +++ be2/src/ia32/codegen-ia32.cc (working copy)
|
| @@ -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();
|
| @@ -6590,6 +6597,47 @@
|
| }
|
|
|
|
|
| +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).
|
| void ToBooleanStub::Generate(MacroAssembler* masm) {
|
| Label false_result, true_result, not_string;
|
|
|