Basic infrastructure for fast two-pass compilation. A CFG is

generated in one-pass from the source AST, code is generated from the
CFG.  Enabled by the flag --multipass and disabled by default.

Rudimentary and currently only supports literal expressions and return
statements.  There are some other known limitations (e.g., missing
support for tracing).

Review URL: http://codereview.chromium.org/159695

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2596 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ddbe148b
......@@ -36,25 +36,26 @@ Import('context')
SOURCES = {
'all': [
'accessors.cc', 'allocation.cc', 'api.cc', 'assembler.cc', 'ast.cc',
'bootstrapper.cc', 'builtins.cc', 'checks.cc', 'code-stubs.cc',
'codegen.cc', 'compilation-cache.cc', 'compiler.cc', 'contexts.cc',
'conversions.cc', 'counters.cc', 'dateparser.cc', 'debug.cc',
'debug-agent.cc', 'disassembler.cc', 'execution.cc', 'factory.cc',
'flags.cc', 'frame-element.cc', 'frames.cc', 'func-name-inferrer.cc',
'global-handles.cc', 'handles.cc', 'hashmap.cc',
'heap.cc', 'ic.cc', 'interpreter-irregexp.cc', 'jsregexp.cc',
'jump-target.cc', 'log.cc', 'log-utils.cc', 'mark-compact.cc', 'messages.cc',
'objects.cc', 'oprofile-agent.cc', 'parser.cc', 'property.cc',
'regexp-macro-assembler.cc', 'regexp-macro-assembler-irregexp.cc',
'regexp-stack.cc', 'register-allocator.cc', 'rewriter.cc', 'runtime.cc',
'scanner.cc', 'scopeinfo.cc', 'scopes.cc', 'serialize.cc',
'snapshot-common.cc', 'spaces.cc', 'string-stream.cc', 'stub-cache.cc',
'token.cc', 'top.cc', 'unicode.cc', 'usage-analyzer.cc', 'utils.cc',
'v8-counters.cc', 'v8.cc', 'v8threads.cc', 'variables.cc', 'version.cc',
'bootstrapper.cc', 'builtins.cc', 'checks.cc', 'cfg.cc',
'code-stubs.cc', 'codegen.cc', 'compilation-cache.cc', 'compiler.cc',
'contexts.cc', 'conversions.cc', 'counters.cc', 'dateparser.cc',
'debug.cc', 'debug-agent.cc', 'disassembler.cc', 'execution.cc',
'factory.cc', 'flags.cc', 'frame-element.cc', 'frames.cc',
'func-name-inferrer.cc', 'global-handles.cc', 'handles.cc',
'hashmap.cc', 'heap.cc', 'ic.cc', 'interpreter-irregexp.cc',
'jsregexp.cc', 'jump-target.cc', 'log.cc', 'log-utils.cc',
'mark-compact.cc', 'messages.cc', 'objects.cc', 'oprofile-agent.cc',
'parser.cc', 'property.cc', 'regexp-macro-assembler.cc',
'regexp-macro-assembler-irregexp.cc', 'regexp-stack.cc',
'register-allocator.cc', 'rewriter.cc', 'runtime.cc', 'scanner.cc',
'scopeinfo.cc', 'scopes.cc', 'serialize.cc', 'snapshot-common.cc',
'spaces.cc', 'string-stream.cc', 'stub-cache.cc', 'token.cc', 'top.cc',
'unicode.cc', 'usage-analyzer.cc', 'utils.cc', 'v8-counters.cc',
'v8.cc', 'v8threads.cc', 'variables.cc', 'version.cc',
'virtual-frame.cc', 'zone.cc'
],
'arch:arm': [
'arm/assembler-arm.cc', 'arm/builtins-arm.cc',
'arm/assembler-arm.cc', 'arm/builtins-arm.cc', 'arm/cfg-arm.cc',
'arm/codegen-arm.cc', 'arm/cpu-arm.cc', 'arm/disasm-arm.cc',
'arm/debug-arm.cc', 'arm/frames-arm.cc', 'arm/ic-arm.cc',
'arm/jump-target-arm.cc', 'arm/macro-assembler-arm.cc',
......@@ -63,7 +64,7 @@ SOURCES = {
'arm/virtual-frame-arm.cc'
],
'arch:ia32': [
'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc',
'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc', 'ia32/cfg-ia32.cc',
'ia32/codegen-ia32.cc', 'ia32/cpu-ia32.cc', 'ia32/disasm-ia32.cc',
'ia32/debug-ia32.cc', 'ia32/frames-ia32.cc', 'ia32/ic-ia32.cc',
'ia32/jump-target-ia32.cc', 'ia32/macro-assembler-ia32.cc',
......@@ -72,7 +73,7 @@ SOURCES = {
'ia32/virtual-frame-ia32.cc'
],
'arch:x64': [
'x64/assembler-x64.cc', 'x64/builtins-x64.cc',
'x64/assembler-x64.cc', 'x64/builtins-x64.cc', 'x64/cfg-x64.cc',
'x64/codegen-x64.cc', 'x64/cpu-x64.cc', 'x64/disasm-x64.cc',
'x64/debug-x64.cc', 'x64/frames-x64.cc', 'x64/ic-x64.cc',
'x64/jump-target-x64.cc', 'x64/macro-assembler-x64.cc',
......
// 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 "cfg.h"
#include "codegen-inl.h"
#include "macro-assembler-arm.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void InstructionBlock::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
{
Comment cmt(masm, "[ InstructionBlock");
for (int i = 0, len = instructions_.length(); i < len; i++) {
instructions_[i]->Compile(masm);
}
}
successor_->Compile(masm);
}
void EntryNode::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
{
Comment cmnt(masm, "[ EntryNode");
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
__ add(fp, sp, Operand(2 * kPointerSize));
if (local_count_ > 0) {
__ mov(ip, Operand(Factory::undefined_value()));
for (int i = 0; i < local_count_; i++) {
__ push(ip);
}
}
if (FLAG_check_stack) {
StackCheckStub stub;
__ CallStub(&stub);
}
}
successor_->Compile(masm);
}
void ExitNode::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
Comment cmnt(masm, "[ ExitNode");
__ mov(sp, fp);
__ ldm(ia_w, sp, fp.bit() | lr.bit());
__ add(sp, sp, Operand((parameter_count_ + 1) * kPointerSize));
__ Jump(lr);
}
void ReturnInstr::Compile(MacroAssembler* masm) {
Comment cmnt(masm, "[ ReturnInstr");
value_->ToRegister(masm, r0);
}
void Constant::ToRegister(MacroAssembler* masm, Register reg) {
__ mov(reg, Operand(handle_));
}
#undef __
} } // namespace v8::internal
This diff is collapsed.
// 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.
#ifndef V8_CFG_H_
#define V8_CFG_H_
#include "ast.h"
namespace v8 {
namespace internal {
// Values appear in instructions. They represent trivial source
// expressions: ones with no side effects and that do not require code to be
// generated.
class Value : public ZoneObject {
public:
virtual void ToRegister(MacroAssembler* masm, Register reg) = 0;
#ifdef DEBUG
virtual void Print() = 0;
#endif
};
// A compile-time constant that appeared as a literal in the source AST.
class Constant : public Value {
public:
explicit Constant(Handle<Object> handle) : handle_(handle) {}
virtual void ToRegister(MacroAssembler* masm, Register reg);
#ifdef DEBUG
void Print();
#endif
private:
Handle<Object> handle_;
};
// Instructions are computations. The represent non-trivial source
// expressions: typically ones that have side effects and require code to
// be generated.
class Instruction : public ZoneObject {
public:
virtual void Compile(MacroAssembler* masm) = 0;
#ifdef DEBUG
virtual void Print() = 0;
#endif
};
// Return a value.
class ReturnInstr : public Instruction {
public:
explicit ReturnInstr(Value* value) : value_(value) {}
void Compile(MacroAssembler* masm);
#ifdef DEBUG
void Print();
#endif
private:
Value* value_;
};
// Nodes make up control-flow graphs. They contain single-entry,
// single-exit blocks of instructions and administrative nodes making up the
// graph structure.
class CfgNode : public ZoneObject {
public:
CfgNode() : is_marked_(false) {
#ifdef DEBUG
number_ = -1;
#endif
}
bool is_marked() { return is_marked_; }
static void Reset();
virtual bool is_block() { return false; }
virtual void Unmark() = 0;
virtual void Compile(MacroAssembler* masm) = 0;
#ifdef DEBUG
int number() {
if (number_ == -1) number_ = node_counter_++;
return number_;
}
virtual void Print() = 0;
#endif
protected:
bool is_marked_;
#ifdef DEBUG
int number_;
static int node_counter_;
#endif
};
// A block is a single-entry, single-exit block of instructions.
class InstructionBlock : public CfgNode {
public:
InstructionBlock() : successor_(NULL), instructions_(4) {}
static InstructionBlock* cast(CfgNode* node) {
ASSERT(node->is_block());
return reinterpret_cast<InstructionBlock*>(node);
}
void set_successor(CfgNode* succ) {
ASSERT(successor_ == NULL);
successor_ = succ;
}
bool is_block() { return true; }
void Unmark();
void Compile(MacroAssembler* masm);
void Append(Instruction* instr) { instructions_.Add(instr); }
#ifdef DEBUG
void Print();
#endif
private:
CfgNode* successor_;
ZoneList<Instruction*> instructions_;
};
// The CFG for a function has a distinguished entry node. It has no
// predecessors and a single successor. The successor is the block
// containing the function's first instruction.
class EntryNode : public CfgNode {
public:
EntryNode(FunctionLiteral* fun, InstructionBlock* succ);
void Unmark();
void Compile(MacroAssembler* masm);
#ifdef DEBUG
void Print();
#endif
private:
InstructionBlock* successor_;
int local_count_;
};
// The CFG for a function has a distinguished exit node. It has no
// successor and arbitrarily many predecessors. The predecessors are all
// the blocks returning from the function.
class ExitNode : public CfgNode {
public:
explicit ExitNode(FunctionLiteral* fun);
void Unmark();
void Compile(MacroAssembler* masm);
#ifdef DEBUG
void Print();
#endif
private:
int parameter_count_;
};
// A CFG is a consists of a linked structure of nodes. It has a single
// entry node and optionally an exit node. There is a distinguished global
// exit node that is used as the successor of all blocks that return from
// the function.
//
// Fragments of control-flow graphs, produced when traversing the statements
// and expressions in the source AST, are represented by the same class.
// They have instruction blocks as both their entry and exit (if there is
// one). Instructions can always be prepended or appended to fragments, and
// fragments can always be concatenated.
//
// A singleton CFG fragment (i.e., with only one node) has the same node as
// both entry and exit (if the exit is available).
class Cfg : public ZoneObject {
public:
// Create a singleton CFG fragment.
explicit Cfg(InstructionBlock* block) : entry_(block), exit_(block) {}
// Build the CFG for a function.
static Cfg* Build(FunctionLiteral* fun);
// The entry and exit nodes.
CfgNode* entry() { return entry_; }
CfgNode* exit() { return exit_; }
// True if the CFG has no nodes.
bool is_empty() { return entry_ == NULL; }
// True if the CFG has an available exit node (i.e., it can be appended or
// concatenated to).
bool has_exit() { return exit_ != NULL; }
// Add an entry node to a CFG fragment. It is no longer a fragment
// (instructions cannot be prepended).
void PrependEntryNode(FunctionLiteral* fun);
// Append an instruction to the end of a CFG fragment. Assumes it has an
// available exit.
void Append(Instruction* instr);
// Appends a return instruction to the end of a CFG fragment. It no
// longer has an available exit node.
void AppendReturnInstruction(Value* value);
Handle<Code> Compile(FunctionLiteral* fun, Handle<Script> script);
#ifdef DEBUG
// Support for printing.
void Print();
#endif
private:
// Reset static variables before building the CFG for a function.
static void Reset(FunctionLiteral* fun);
// Shared global exit nodes for all returns from the same function.
static ExitNode* global_exit_;
// Entry and exit nodes.
CfgNode* entry_;
CfgNode* exit_;
};
// An Expression Builder traverses a trivial expression and returns a value.
class ExpressionBuilder : public AstVisitor {
public:
ExpressionBuilder() : value_(new Constant(Handle<Object>::null())) {}
Value* value() { return value_; }
// AST node visitors.
#define DECLARE_VISIT(type) void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
private:
Value* value_;
};
// A StatementBuilder traverses a statement and returns a CFG.
class StatementBuilder : public AstVisitor {
public:
StatementBuilder() : cfg_(new Cfg(new InstructionBlock())) {}
Cfg* cfg() { return cfg_; }
void VisitStatements(ZoneList<Statement*>* stmts);
// AST node visitors.
#define DECLARE_VISIT(type) void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
private:
Cfg* cfg_;
};
} } // namespace v8::internal
#endif // V8_CFG_H_
......@@ -28,6 +28,7 @@
#include "v8.h"
#include "bootstrapper.h"
#include "cfg.h"
#include "codegen-inl.h"
#include "compilation-cache.h"
#include "compiler.h"
......@@ -78,6 +79,21 @@ static Handle<Code> MakeCode(FunctionLiteral* literal,
return Handle<Code>::null();
}
if (FLAG_multipass) {
Cfg* cfg = Cfg::Build(literal);
#ifdef DEBUG
if (FLAG_print_cfg && cfg != NULL) {
SmartPointer<char> name = literal->name()->ToCString();
PrintF("Function \"%s\":\n", *name);
cfg->Print();
PrintF("\n");
}
#endif
if (cfg != NULL) {
return cfg->Compile(literal, script);
}
}
// Generate code and return it.
Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
return result;
......
......@@ -133,6 +133,7 @@ DEFINE_bool(debug_info, true, "add debug information to compiled functions")
DEFINE_bool(strict, false, "strict error checking")
DEFINE_int(min_preparse_length, 1024,
"Minimum length for automatic enable preparsing")
DEFINE_bool(multipass, false, "use the multipass code generator")
// compilation-cache.cc
DEFINE_bool(compilation_cache, true, "enable compilation cache")
......@@ -267,6 +268,7 @@ DEFINE_string(stop_at, "", "function name where to insert a breakpoint")
// compiler.cc
DEFINE_bool(print_builtin_scopes, false, "print scopes for builtins")
DEFINE_bool(print_scopes, false, "print scopes")
DEFINE_bool(print_cfg, false, "print control-flow graph")
// contexts.cc
DEFINE_bool(trace_contexts, false, "trace contexts operations")
......
// 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 "cfg.h"
#include "codegen-inl.h"
#include "macro-assembler-ia32.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void InstructionBlock::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
{
Comment cmt(masm, "[ InstructionBlock");
for (int i = 0, len = instructions_.length(); i < len; i++) {
instructions_[i]->Compile(masm);
}
}
successor_->Compile(masm);
}
void EntryNode::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
Label deferred_enter, deferred_exit;
{
Comment cmnt(masm, "[ EntryNode");
__ push(ebp);
__ mov(ebp, esp);
__ push(esi);
__ push(edi);
if (local_count_ > 0) {
__ Set(eax, Immediate(Factory::undefined_value()));
for (int i = 0; i < local_count_; i++) {
__ push(eax);
}
}
if (FLAG_check_stack) {
ExternalReference stack_limit =
ExternalReference::address_of_stack_guard_limit();
__ cmp(esp, Operand::StaticVariable(stack_limit));
__ j(below, &deferred_enter);
__ bind(&deferred_exit);
}
}
successor_->Compile(masm);
if (FLAG_check_stack) {
__ bind(&deferred_enter);
StackCheckStub stub;
__ CallStub(&stub);
__ jmp(&deferred_exit);
}
}
void ExitNode::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
Comment cmnt(masm, "[ ExitNode");
__ RecordJSReturn();
__ mov(esp, ebp);
__ pop(ebp);
__ ret((parameter_count_ + 1) * kPointerSize);
}
void ReturnInstr::Compile(MacroAssembler* masm) {
Comment cmnt(masm, "[ ReturnInstr");
value_->ToRegister(masm, eax);
}
void Constant::ToRegister(MacroAssembler* masm, Register reg) {
__ mov(reg, Immediate(handle_));
}
#undef __
} } // namespace v8::internal
// 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 "cfg.h"
#include "codegen-inl.h"
#include "debug.h"
#include "macro-assembler-x64.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void InstructionBlock::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
{
Comment cmt(masm, "[ InstructionBlock");
for (int i = 0, len = instructions_.length(); i < len; i++) {
instructions_[i]->Compile(masm);
}
}
successor_->Compile(masm);
}
void EntryNode::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
Label deferred_enter, deferred_exit;
{
Comment cmnt(masm, "[ EntryNode");
__ push(rbp);
__ movq(rbp, rsp);
__ push(rsi);
__ push(rdi);
if (local_count_ > 0) {
__ movq(kScratchRegister, Factory::undefined_value(),
RelocInfo::EMBEDDED_OBJECT);
for (int i = 0; i < local_count_; i++) {
__ push(kScratchRegister);
}
}
if (FLAG_check_stack) {
ExternalReference stack_limit =
ExternalReference::address_of_stack_guard_limit();
__ movq(kScratchRegister, stack_limit);
__ cmpq(rsp, Operand(kScratchRegister, 0));
__ j(below, &deferred_enter);
__ bind(&deferred_exit);
}
}
successor_->Compile(masm);
if (FLAG_check_stack) {
__ bind(&deferred_enter);
StackCheckStub stub;
__ CallStub(&stub);
__ jmp(&deferred_exit);
}
}
void ExitNode::Compile(MacroAssembler* masm) {
ASSERT(!is_marked());
is_marked_ = true;
Comment cmnt(masm, "[ ExitNode");
__ RecordJSReturn();
__ movq(rsp, rbp);
__ pop(rbp);
__ ret((parameter_count_ + 1) * kPointerSize);
// Add padding that will be overwritten by a debugger breakpoint.
// "movq rsp, rbp; pop rbp" has length 5. "ret k" has length 2.
const int kPadding = Debug::kX64JSReturnSequenceLength - 5 - 2;
for (int i = 0; i < kPadding; ++i) {
__ int3();
}
}
void ReturnInstr::Compile(MacroAssembler* masm) {
Comment cmnt(masm, "[ ReturnInstr");
value_->ToRegister(masm, rax);
}
void Constant::ToRegister(MacroAssembler* masm, Register reg) {
__ Move(reg, handle_);
}
#undef __
} } // namespace v8::internal
......@@ -40,7 +40,7 @@
'defines': [
'ENABLE_LOGGING_AND_PROFILING',
],
'conditions': [
'conditions': [
['target_arch=="arm"', {
'defines': [
'V8_TARGET_ARCH_ARM',
......@@ -216,6 +216,8 @@
'../../src/builtins.cc',
'../../src/builtins.h',
'../../src/bytecodes-irregexp.h',
'../../src/cfg.cc',
'../../src/cfg.h',
'../../src/char-predicates-inl.h',
'../../src/char-predicates.h',
'../../src/checks.cc',
......@@ -383,6 +385,7 @@
'../../src/arm/assembler-arm.cc',
'../../src/arm/assembler-arm.h',
'../../src/arm/builtins-arm.cc',
'../../src/arm/cfg-arm.cc',
'../../src/arm/codegen-arm.cc',
'../../src/arm/codegen-arm.h',
'../../src/arm/constants-arm.h',
......@@ -413,6 +416,7 @@
'../../src/ia32/assembler-ia32.cc',
'../../src/ia32/assembler-ia32.h',
'../../src/ia32/builtins-ia32.cc',
'../../src/ia32/cfg-ia32.cc',
'../../src/ia32/codegen-ia32.cc',
'../../src/ia32/codegen-ia32.h',
'../../src/ia32/cpu-ia32.cc',
......@@ -441,6 +445,7 @@
'../../src/x64/assembler-x64.cc',
'../../src/x64/assembler-x64.h',
'../../src/x64/builtins-x64.cc',
'../../src/x64/cfg-x64.cc',
'../../src/x64/codegen-x64.cc',
'../../src/x64/codegen-x64.h',
'../../src/x64/cpu-x64.cc',
......
......@@ -236,6 +236,18 @@
RelativePath="..\..\src\bytecodes-irregexp.h"
>
</File>
<File
RelativePath="..\..\src\ia32\cfg-ia32.cc"
>
</File>
<File
RelativePath="..\..\src\cfg.cc"
>
</File>
<File
RelativePath="..\..\src\cfg.h"
>
</File>
<File
RelativePath="..\..\src\char-predicates-inl.h"
>
......
......@@ -236,6 +236,18 @@
RelativePath="..\..\src\bytecodes-irregexp.h"
>
</File>
<File
RelativePath="..\..\src\arm\cfg-arm.cc"
>
</File>
<File
RelativePath="..\..\src\cfg.cc"
>
</File>
<File
RelativePath="..\..\src\cfg.h"
>
</File>
<File
RelativePath="..\..\src\char-predicates-inl.h"
>
......
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