From 7358e1980cd02221d210a2cd2153f3a30b604e28 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Tue, 16 Jun 2009 08:25:08 +0000 Subject: [PATCH] X64 implementation: Test Compiler::Compile by compiling and running a function. Review URL: http://codereview.chromium.org/126191 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2178 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/codegen-x64.cc | 171 +++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 67 deletions(-) diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index b1f296c2a..dc32227b4 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -30,6 +30,8 @@ #include "macro-assembler.h" #include "register-allocator-inl.h" #include "codegen.h" +// TEST +#include "compiler.h" namespace v8 { namespace internal { @@ -97,84 +99,119 @@ void CodeGenerator::DeclareGlobals(Handle a) { } void CodeGenerator::TestCodeGenerator() { - // Generate code. - ZoneScope zone_scope(DELETE_ON_EXIT); - const int initial_buffer_size = 4 * KB; - CodeGenerator cgen(initial_buffer_size, NULL, false); - CodeGeneratorScope scope(&cgen); - Scope dummy_scope; - cgen.scope_ = &dummy_scope; - cgen.GenCode(NULL); - - CodeDesc desc; - cgen.masm()->GetCode(&desc); + // Compile a function from a string, and run it. + Handle test_function = Compiler::Compile( + Factory::NewStringFromAscii(CStrVector("42")), + Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), + 0, + 0, + NULL, + NULL); + + Code* code_object = test_function->code(); // Local for debugging ease. + USE(code_object); + + // Create a dummy function and context. + Handle bridge = + Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value()); + Handle context = + Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); + + test_function = Factory::NewFunctionFromBoilerplate( + test_function, + context); + + bool pending_exceptions; + Handle result = + Execution::Call(test_function, + Handle::cast(test_function), + 0, + NULL, + &pending_exceptions); + CHECK(result->IsSmi()); + CHECK_EQ(42, Smi::cast(*result)->value()); } void CodeGenerator::GenCode(FunctionLiteral* function) { - if (function != NULL) { - CodeForFunctionPosition(function); - // ASSERT(scope_ == NULL); - // scope_ = function->scope(); - __ int3(); // UNIMPLEMENTED - } else { - // GenCode Implementation under construction. Run by TestCodeGenerator - // with a == NULL. - // Everything guarded by if (function) should be run, unguarded, - // once testing is over. - // Record the position for debugging purposes. - if (function) { - CodeForFunctionPosition(function); - } - // ZoneList* body = fun->body(); - - // Initialize state. - // While testing, scope is set in cgen before calling GenCode(). - if (function) { - ASSERT(scope_ == NULL); - scope_ = function->scope(); - } - ASSERT(allocator_ == NULL); - RegisterAllocator register_allocator(this); - allocator_ = ®ister_allocator; - ASSERT(frame_ == NULL); - frame_ = new VirtualFrame(); - set_in_spilled_code(false); - - // Adjust for function-level loop nesting. - // loop_nesting_ += fun->loop_nesting(); - - JumpTarget::set_compiling_deferred_code(false); + // Record the position for debugging purposes. + CodeForFunctionPosition(function); + // ZoneList* body = fun->body(); + + // Initialize state. + ASSERT(scope_ == NULL); + scope_ = function->scope(); + ASSERT(allocator_ == NULL); + RegisterAllocator register_allocator(this); + allocator_ = ®ister_allocator; + ASSERT(frame_ == NULL); + frame_ = new VirtualFrame(); + set_in_spilled_code(false); + + // Adjust for function-level loop nesting. + loop_nesting_ += function->loop_nesting(); + + JumpTarget::set_compiling_deferred_code(false); #ifdef DEBUG - if (strlen(FLAG_stop_at) > 0 && - // fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { - false) { - frame_->SpillAll(); - __ int3(); - } + if (strlen(FLAG_stop_at) > 0 && + // fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { + false) { + frame_->SpillAll(); + __ int3(); + } #endif - // New scope to get automatic timing calculation. - { // NOLINT - HistogramTimerScope codegen_timer(&Counters::code_generation); - CodeGenState state(this); - - // Entry: - // Stack: receiver, arguments, return address. - // ebp: caller's frame pointer - // esp: stack pointer - // edi: called JS function - // esi: callee's context - allocator_->Initialize(); - frame_->Enter(); - - __ movq(rax, Immediate(0x2a)); - __ Ret(); - } + // New scope to get automatic timing calculation. + { // NOLINT + HistogramTimerScope codegen_timer(&Counters::code_generation); + CodeGenState state(this); + + // Entry: + // Stack: receiver, arguments, return address. + // ebp: caller's frame pointer + // esp: stack pointer + // edi: called JS function + // esi: callee's context + allocator_->Initialize(); + frame_->Enter(); + + Result return_register = allocator_->Allocate(rax); + + __ movq(return_register.reg(), Immediate(0x54)); // Smi 42 + + GenerateReturnSequence(&return_register); + } +} + +void CodeGenerator::GenerateReturnSequence(Result* return_value) { + // The return value is a live (but not currently reference counted) + // reference to rax. This is safe because the current frame does not + // contain a reference to rax (it is prepared for the return by spilling + // all registers). + if (FLAG_trace) { + frame_->Push(return_value); + // *return_value = frame_->CallRuntime(Runtime::kTraceExit, 1); } + return_value->ToRegister(rax); + + // Add a label for checking the size of the code used for returning. + Label check_exit_codesize; + masm_->bind(&check_exit_codesize); + + // Leave the frame and return popping the arguments and the + // receiver. + frame_->Exit(); + masm_->ret((scope_->num_parameters() + 1) * kPointerSize); + DeleteFrame(); + + // Check that the size of the code used for returning matches what is + // expected by the debugger. + // ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, + // masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); } + void CodeGenerator::GenerateFastCaseSwitchJumpTable(SwitchStatement* a, int b, int c, -- 2.34.1