Commit 7358e198 authored by whesse@chromium.org's avatar whesse@chromium.org

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
parent fb03c841
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "macro-assembler.h" #include "macro-assembler.h"
#include "register-allocator-inl.h" #include "register-allocator-inl.h"
#include "codegen.h" #include "codegen.h"
// TEST
#include "compiler.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -97,84 +99,119 @@ void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) { ...@@ -97,84 +99,119 @@ void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) {
} }
void CodeGenerator::TestCodeGenerator() { void CodeGenerator::TestCodeGenerator() {
// Generate code. // Compile a function from a string, and run it.
ZoneScope zone_scope(DELETE_ON_EXIT); Handle<JSFunction> test_function = Compiler::Compile(
const int initial_buffer_size = 4 * KB; Factory::NewStringFromAscii(CStrVector("42")),
CodeGenerator cgen(initial_buffer_size, NULL, false); Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")),
CodeGeneratorScope scope(&cgen); 0,
Scope dummy_scope; 0,
cgen.scope_ = &dummy_scope; NULL,
cgen.GenCode(NULL); NULL);
CodeDesc desc; Code* code_object = test_function->code(); // Local for debugging ease.
cgen.masm()->GetCode(&desc); USE(code_object);
// Create a dummy function and context.
Handle<JSFunction> bridge =
Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value());
Handle<Context> context =
Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
test_function = Factory::NewFunctionFromBoilerplate(
test_function,
context);
bool pending_exceptions;
Handle<Object> result =
Execution::Call(test_function,
Handle<Object>::cast(test_function),
0,
NULL,
&pending_exceptions);
CHECK(result->IsSmi());
CHECK_EQ(42, Smi::cast(*result)->value());
} }
void CodeGenerator::GenCode(FunctionLiteral* function) { void CodeGenerator::GenCode(FunctionLiteral* function) {
if (function != NULL) { // Record the position for debugging purposes.
CodeForFunctionPosition(function); CodeForFunctionPosition(function);
// ASSERT(scope_ == NULL); // ZoneList<Statement*>* body = fun->body();
// scope_ = function->scope();
__ int3(); // UNIMPLEMENTED // Initialize state.
} else { ASSERT(scope_ == NULL);
// GenCode Implementation under construction. Run by TestCodeGenerator scope_ = function->scope();
// with a == NULL. ASSERT(allocator_ == NULL);
// Everything guarded by if (function) should be run, unguarded, RegisterAllocator register_allocator(this);
// once testing is over. allocator_ = &register_allocator;
// Record the position for debugging purposes. ASSERT(frame_ == NULL);
if (function) { frame_ = new VirtualFrame();
CodeForFunctionPosition(function); set_in_spilled_code(false);
}
// ZoneList<Statement*>* body = fun->body(); // Adjust for function-level loop nesting.
loop_nesting_ += function->loop_nesting();
// Initialize state.
// While testing, scope is set in cgen before calling GenCode(). JumpTarget::set_compiling_deferred_code(false);
if (function) {
ASSERT(scope_ == NULL);
scope_ = function->scope();
}
ASSERT(allocator_ == NULL);
RegisterAllocator register_allocator(this);
allocator_ = &register_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);
#ifdef DEBUG #ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 && if (strlen(FLAG_stop_at) > 0 &&
// fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { // fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
false) { false) {
frame_->SpillAll(); frame_->SpillAll();
__ int3(); __ int3();
} }
#endif #endif
// New scope to get automatic timing calculation. // New scope to get automatic timing calculation.
{ // NOLINT { // NOLINT
HistogramTimerScope codegen_timer(&Counters::code_generation); HistogramTimerScope codegen_timer(&Counters::code_generation);
CodeGenState state(this); CodeGenState state(this);
// Entry: // Entry:
// Stack: receiver, arguments, return address. // Stack: receiver, arguments, return address.
// ebp: caller's frame pointer // ebp: caller's frame pointer
// esp: stack pointer // esp: stack pointer
// edi: called JS function // edi: called JS function
// esi: callee's context // esi: callee's context
allocator_->Initialize(); allocator_->Initialize();
frame_->Enter(); frame_->Enter();
__ movq(rax, Immediate(0x2a)); Result return_register = allocator_->Allocate(rax);
__ Ret();
} __ 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, void CodeGenerator::GenerateFastCaseSwitchJumpTable(SwitchStatement* a,
int b, int b,
int c, int c,
......
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