Revision: 3071 Author: [email protected] Date: Thu Oct 15 04:21:26 2009 Log: Port the initial fast code generator to x64. For the constant true in top-level code we generate:
0 push rbp 1 movq rbp,rsp 4 push rsi 5 push rdi 6 push [r13+0x8] 10 cmpq rsp,[r13+0x0] 14 jnc 25 (0x7ff2c378ff19) 20 call 0x7ff2c377d260 ;; code: STUB, StackCheck, minor: 0 25 movq r10,0x7ff2e8608199 ;; object: 0x7ff2e8608199 <true> 35 push r10 37 movq rax,[rsp] 41 movq [rbp-0x18],rax 45 pop rax 46 push [rbp-0x18] 50 pop rax 51 movq rsp,rbp ;; js return 54 pop rbp 55 ret 0x8 58 int3 59 int3 60 int3 61 int3 62 int3 63 int3 64 movq rax,[r13+0x8] 68 movq rsp,rbp ;; js return 71 pop rbp 72 ret 0x8 75 int3 76 int3 77 int3 78 int3 79 int3 80 int3 Review URL: http://codereview.chromium.org/264066 http://code.google.com/p/v8/source/detail?r=3071 Added: /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Modified: /branches/bleeding_edge/src/SConscript /branches/bleeding_edge/src/compiler.cc /branches/bleeding_edge/src/fast-codegen.cc /branches/bleeding_edge/src/fast-codegen.h /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc /branches/bleeding_edge/src/x64/frames-x64.h /branches/bleeding_edge/tools/gyp/v8.gyp ======================================= --- /dev/null +++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Thu Oct 15 04:21:26 2009 @@ -0,0 +1,157 @@ +// Copyright 2009 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "v8.h" + +#include "codegen-inl.h" +#include "debug.h" +#include "fast-codegen.h" + +namespace v8 { +namespace internal { + +#define __ ACCESS_MASM(masm_) + +// Generate code for a JS function. On entry to the function the receiver +// and arguments have been pushed on the stack left to right, with the +// return address on top of them. The actual argument count matches the +// formal parameter count expected by the function. +// +// The live registers are: +// o rdi: the JS function object being called (ie, ourselves) +// o rsi: our context +// o rbp: our caller's frame pointer +// o rsp: stack pointer (pointing to return address) +// +// The function builds a JS frame. Please see JavaScriptFrameConstants in +// frames-x64.h for its layout. +void FastCodeGenerator::Generate(FunctionLiteral* fun) { + function_ = fun; + + __ push(rbp); // Caller's frame pointer. + __ movq(rbp, rsp); + __ push(rsi); // Callee's context. + __ push(rdi); // Callee's JS Function. + + { Comment cmnt(masm_, "[ Allocate locals"); + int locals_count = fun->scope()->num_stack_slots(); + for (int i = 0; i < locals_count; i++) { + __ PushRoot(Heap::kUndefinedValueRootIndex); + } + } + + { Comment cmnt(masm_, "[ Stack check"); + Label ok; + __ CompareRoot(rsp, Heap::kStackLimitRootIndex); + __ j(above_equal, &ok); + StackCheckStub stub; + __ CallStub(&stub); + __ bind(&ok); + } + + { Comment cmnt(masm_, "[ Body"); + VisitStatements(fun->body()); + } + + { Comment cmnt(masm_, "[ return <undefined>;"); + // Emit a 'return undefined' in case control fell off the end of the + // body. + __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); + __ RecordJSReturn(); + // Do not use the leave instruction here because it is too short to + // patch with the code required by the debugger. + __ movq(rsp, rbp); + __ pop(rbp); + __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); +#ifdef ENABLE_DEBUGGER_SUPPORT + // Add padding that will be overwritten by a debugger breakpoint. We + // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7 + // (3 + 1 + 3). + const int kPadding = Debug::kX64JSReturnSequenceLength - 7; + for (int i = 0; i < kPadding; ++i) { + masm_->int3(); + } +#endif + } +} + + +void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { + Comment cmnt(masm_, "[ ExpressionStatement"); + Visit(stmt->expression()); + __ pop(rax); +} + + +void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { + Comment cmnt(masm_, "[ ReturnStatement"); + Visit(stmt->expression()); + __ pop(rax); + __ RecordJSReturn(); + // Do not use the leave instruction here because it is too short to + // patch with the code required by the debugger. + __ movq(rsp, rbp); + __ pop(rbp); + __ ret((function_->scope()->num_parameters() + 1) * kPointerSize); +#ifdef ENABLE_DEBUGGER_SUPPORT + // Add padding that will be overwritten by a debugger breakpoint. We + // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7 + // (3 + 1 + 3). + const int kPadding = Debug::kX64JSReturnSequenceLength - 7; + for (int i = 0; i < kPadding; ++i) { + masm_->int3(); + } +#endif +} + + +void FastCodeGenerator::VisitSlot(Slot* expr) { + Comment cmnt(masm_, "[ Slot"); + __ push(Operand(rbp, SlotOffset(expr))); +} + + +void FastCodeGenerator::VisitLiteral(Literal* expr) { + Comment cmnt(masm_, "[ Literal"); + __ Push(expr->handle()); +} + + +void FastCodeGenerator::VisitAssignment(Assignment* expr) { + Comment cmnt(masm_, "[ Assignment"); + ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); + + Visit(expr->value()); + + Variable* var = expr->target()->AsVariableProxy()->AsVariable(); + ASSERT(var != NULL && var->slot() != NULL); + __ movq(rax, Operand(rsp, 0)); + __ movq(Operand(rbp, SlotOffset(var->slot())), rax); +} + + +} } // namespace v8::internal ======================================= --- /branches/bleeding_edge/src/SConscript Thu Oct 15 01:22:24 2009 +++ /branches/bleeding_edge/src/SConscript Thu Oct 15 04:21:26 2009 @@ -140,12 +140,14 @@ ia32/virtual-frame-ia32.cc """), 'arch:x64': Split(""" + fast-codegen.cc x64/assembler-x64.cc x64/builtins-x64.cc x64/codegen-x64.cc x64/cpu-x64.cc x64/debug-x64.cc x64/disasm-x64.cc + x64/fast-codegen-x64.cc x64/frames-x64.cc x64/ic-x64.cc x64/jump-target-x64.cc ======================================= --- /branches/bleeding_edge/src/compiler.cc Wed Oct 14 12:30:50 2009 +++ /branches/bleeding_edge/src/compiler.cc Thu Oct 15 04:21:26 2009 @@ -41,7 +41,7 @@ namespace v8 { namespace internal { -#ifdef V8_TARGET_ARCH_IA32 +#ifndef V8_TARGET_ARCH_ARM class CodeGenSelector: public AstVisitor { public: @@ -106,7 +106,7 @@ } // Generate code and return it. -#ifdef V8_TARGET_ARCH_IA32 +#ifndef V8_TARGET_ARCH_ARM if (FLAG_fast_compiler) { CodeGenSelector selector; CodeGenSelector::CodeGenTag code_gen = selector.Select(literal); @@ -453,7 +453,7 @@ } -#ifdef V8_TARGET_ARCH_IA32 +#ifndef V8_TARGET_ARCH_ARM CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) { Scope* scope = fun->scope(); @@ -718,7 +718,7 @@ #undef BAILOUT #undef CHECK_BAILOUT -#endif // V8_TARGET_ARCH_IA32 +#endif // !defined(V8_TARGET_ARCH_ARM) } } // namespace v8::internal ======================================= --- /branches/bleeding_edge/src/fast-codegen.cc Wed Oct 14 12:30:50 2009 +++ /branches/bleeding_edge/src/fast-codegen.cc Thu Oct 15 04:21:26 2009 @@ -161,6 +161,14 @@ void FastCodeGenerator::VisitConditional(Conditional* expr) { UNREACHABLE(); } + + +void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { + Comment cmnt(masm_, "[ VariableProxy"); + Expression* rewrite = expr->var()->rewrite(); + ASSERT(rewrite != NULL); + Visit(rewrite); +} void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ======================================= --- /branches/bleeding_edge/src/fast-codegen.h Wed Oct 14 12:30:50 2009 +++ /branches/bleeding_edge/src/fast-codegen.h Thu Oct 15 04:21:26 2009 @@ -28,7 +28,7 @@ #ifndef V8_FAST_CODEGEN_H_ #define V8_FAST_CODEGEN_H_ -#ifdef V8_TARGET_ARCH_IA32 +#ifndef V8_TARGET_ARCH_ARM #include "v8.h" @@ -63,5 +63,5 @@ } } // namespace v8::internal -#endif // V8_TARGET_ARCH_IA32 +#endif // !defined(V8_TARGET_ARCH_ARM) #endif // V8_FAST_CODEGEN_H_ ======================================= --- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Wed Oct 14 12:30:50 2009 +++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Thu Oct 15 04:21:26 2009 @@ -29,7 +29,6 @@ #include "codegen-inl.h" #include "fast-codegen.h" -// #include "scopes.h" namespace v8 { namespace internal { @@ -116,14 +115,6 @@ Comment cmnt(masm_, "[ Slot"); __ push(Operand(ebp, SlotOffset(expr))); } - - -void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { - Comment cmnt(masm_, "[ VariableProxy"); - Expression* rewrite = expr->var()->rewrite(); - ASSERT(rewrite != NULL); - Visit(rewrite); -} void FastCodeGenerator::VisitLiteral(Literal* expr) { ======================================= --- /branches/bleeding_edge/src/x64/frames-x64.h Thu Aug 27 23:18:36 2009 +++ /branches/bleeding_edge/src/x64/frames-x64.h Thu Oct 15 04:21:26 2009 @@ -31,9 +31,6 @@ namespace v8 { namespace internal { -// TODO(x64): This is a stub, mostly just a copy of the ia32 bit version. -// This might all need to change to be correct for x64. - static const int kNumRegs = 8; static const RegList kJSCallerSaved = 1 << 0 | // rax ======================================= --- /branches/bleeding_edge/tools/gyp/v8.gyp Wed Oct 14 12:47:22 2009 +++ /branches/bleeding_edge/tools/gyp/v8.gyp Thu Oct 15 04:21:26 2009 @@ -445,6 +445,8 @@ '../../src/x64', ], 'sources': [ + '../../src/fast-codegen.cc', + '../../src/fast-codegen.h', '../../src/x64/assembler-x64-inl.h', '../../src/x64/assembler-x64.cc', '../../src/x64/assembler-x64.h', @@ -454,6 +456,7 @@ '../../src/x64/cpu-x64.cc', '../../src/x64/debug-x64.cc', '../../src/x64/disasm-x64.cc', + '../../src/x64/fast-codegen-x64.cc', '../../src/x64/frames-x64.cc', '../../src/x64/frames-x64.h', '../../src/x64/ic-x64.cc', --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
