Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: bleeding_edge/src/ia32/codegen-ia32.cc

Issue 506037: Improve performance of allocating closures for nested... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3575 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 #ifdef ENABLE_DEBUGGER_SUPPORT 3586 #ifdef ENABLE_DEBUGGER_SUPPORT
3587 // Spill everything, even constants, to the frame. 3587 // Spill everything, even constants, to the frame.
3588 frame_->SpillAll(); 3588 frame_->SpillAll();
3589 frame_->CallRuntime(Runtime::kDebugBreak, 0); 3589 frame_->CallRuntime(Runtime::kDebugBreak, 0);
3590 // Ignore the return value. 3590 // Ignore the return value.
3591 #endif 3591 #endif
3592 } 3592 }
3593 3593
3594 3594
3595 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 3595 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
3596 // Call the runtime to instantiate the function boilerplate object.
3597 // The inevitable call will sync frame elements to memory anyway, so
3598 // we do it eagerly to allow us to push the arguments directly into
3599 // place.
3600 ASSERT(boilerplate->IsBoilerplate()); 3596 ASSERT(boilerplate->IsBoilerplate());
3601 frame_->SyncRange(0, frame_->element_count() - 1);
3602 3597
3603 // Create a new closure. 3598 // Use the fast case closure allocation code that allocated in new
Mads Ager (chromium) 2009/12/16 16:13:24 allocated -> allocates
3604 frame_->EmitPush(esi); 3599 // space when for nested functions that don't need literals cloning.
bakster 2009/12/16 15:40:38 remove when
3605 frame_->EmitPush(Immediate(boilerplate)); 3600 if (scope()->is_function_scope() && boilerplate->NumberOfLiterals() == 0) {
3606 Result result = frame_->CallRuntime(Runtime::kNewClosure, 2); 3601 FastNewClosureStub stub;
3607 frame_->Push(&result); 3602 frame_->Push(boilerplate);
3603 Result answer = frame_->CallStub(&stub, 1);
3604 frame_->Push(&answer);
3605 } else {
3606 // Call the runtime to instantiate the function boilerplate
3607 // object. The inevitable call will sync frame elements to memory
3608 // anyway, so we do it eagerly to allow us to push the arguments
3609 // directly into place.
3610 frame_->SyncRange(0, frame_->element_count() - 1);
3611
3612 // Create a new closure.
3613 frame_->EmitPush(esi);
3614 frame_->EmitPush(Immediate(boilerplate));
3615 Result result = frame_->CallRuntime(Runtime::kNewClosure, 2);
3616 frame_->Push(&result);
3617 }
3608 } 3618 }
3609 3619
3610 3620
3611 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 3621 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
3612 Comment cmnt(masm_, "[ FunctionLiteral"); 3622 Comment cmnt(masm_, "[ FunctionLiteral");
3613 3623
3614 // Build the function boilerplate and instantiate it. 3624 // Build the function boilerplate and instantiate it.
3615 Handle<JSFunction> boilerplate = 3625 Handle<JSFunction> boilerplate =
3616 Compiler::BuildBoilerplate(node, script_, this); 3626 Compiler::BuildBoilerplate(node, script_, this);
3617 // Check for stack-overflow exception. 3627 // Check for stack-overflow exception.
(...skipping 2912 matching lines...) Expand 10 before | Expand all | Expand 10 after
6530 } 6540 }
6531 break; 6541 break;
6532 } 6542 }
6533 6543
6534 default: 6544 default:
6535 UNREACHABLE(); 6545 UNREACHABLE();
6536 } 6546 }
6537 } 6547 }
6538 6548
6539 6549
6550 void FastNewClosureStub::Generate(MacroAssembler* masm) {
6551 // Clone the boilerplate in new space. Set the context to the
6552 // current context in esi.
6553 Label gc;
6554 __ AllocateInNewSpace(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
6555
6556 // Get the boilerplate function from the stack.
6557 __ mov(edx, Operand(esp, 1 * kPointerSize));
6558
6559 // Compute the function map in the current global context and set that
6560 // as the map of the allocated object.
6561 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
6562 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
6563 __ mov(ecx, Operand(ecx, Context::SlotOffset(Context::FUNCTION_MAP_INDEX)));
6564 __ mov(FieldOperand(eax, JSObject::kMapOffset), ecx);
6565
6566 // Clone the rest of the boilerplate fields. We don't have to update
6567 // the write barrier because the allocated object is in new space.
6568 for (int offset = kPointerSize;
6569 offset < JSFunction::kSize;
6570 offset += kPointerSize) {
6571 if (offset == JSFunction::kContextOffset) {
6572 __ mov(FieldOperand(eax, offset), esi);
6573 } else {
6574 __ mov(ebx, FieldOperand(edx, offset));
6575 __ mov(FieldOperand(eax, offset), ebx);
6576 }
6577 }
6578
6579 // Return and remove the on-stack parameter.
6580 __ ret(1 * kPointerSize);
6581
6582 // Create a new closure through the slower runtime call.
6583 __ bind(&gc);
6584 __ pop(ecx); // Temporarily remove return address.
6585 __ pop(edx);
6586 __ push(esi);
6587 __ push(edx);
6588 __ push(ecx); // Restore return address.
6589 __ TailCallRuntime(ExternalReference(Runtime::kNewClosure), 2, 1);
6590 }
6591
6592
6540 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). 6593 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined).
6541 void ToBooleanStub::Generate(MacroAssembler* masm) { 6594 void ToBooleanStub::Generate(MacroAssembler* masm) {
6542 Label false_result, true_result, not_string; 6595 Label false_result, true_result, not_string;
6543 __ mov(eax, Operand(esp, 1 * kPointerSize)); 6596 __ mov(eax, Operand(esp, 1 * kPointerSize));
6544 6597
6545 // 'null' => false. 6598 // 'null' => false.
6546 __ cmp(eax, Factory::null_value()); 6599 __ cmp(eax, Factory::null_value());
6547 __ j(equal, &false_result); 6600 __ j(equal, &false_result);
6548 6601
6549 // Get the map and type of the heap object. 6602 // Get the map and type of the heap object.
(...skipping 1908 matching lines...) Expand 10 before | Expand all | Expand 10 after
8458 __ add(Operand(dest), Immediate(2)); 8511 __ add(Operand(dest), Immediate(2));
8459 } 8512 }
8460 __ sub(Operand(count), Immediate(1)); 8513 __ sub(Operand(count), Immediate(1));
8461 __ j(not_zero, &loop); 8514 __ j(not_zero, &loop);
8462 } 8515 }
8463 8516
8464 8517
8465 #undef __ 8518 #undef __
8466 8519
8467 } } // namespace v8::internal 8520 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698