105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifndef V8_FULL_CODEGEN_H_ 6b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define V8_FULL_CODEGEN_H_ 7b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assert-scope.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ast.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/data-flow.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/globals.h" 18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/objects.h" 19b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 20b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace v8 { 21b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace internal { 22b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Forward declarations. 245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgclass JumpPatchSite; 255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org// AST node visitor which can tell whether a given statement will be breakable 272356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org// when the code is compiled by the full compiler in the debugger. This means 282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org// that there will be an IC (load/store/call) in the code generated for the 292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org// debugger to piggybag on. 302356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgclass BreakableStatementChecker: public AstVisitor { 312356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org public: 326d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org explicit BreakableStatementChecker(Zone* zone) : is_breakable_(false) { 336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org InitializeAstVisitor(zone); 34a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 352356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 362356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org void Check(Statement* stmt); 372356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org void Check(Expression* stmt); 382356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 392356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org bool is_breakable() { return is_breakable_; } 402356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 412356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org private: 422356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // AST node visit functions. 432356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org#define DECLARE_VISIT(type) virtual void Visit##type(type* node); 442356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org AST_NODE_LIST(DECLARE_VISIT) 452356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org#undef DECLARE_VISIT 462356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 472356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org bool is_breakable_; 482356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 49a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 502356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org DISALLOW_COPY_AND_ASSIGN(BreakableStatementChecker); 512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org}; 522356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 532356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 54b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// ----------------------------------------------------------------------------- 55b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Full code generator. 56b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 57b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass FullCodeGenerator: public AstVisitor { 58b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org enum State { 60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org NO_REGISTERS, 61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org TOS_REG 62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info) 65b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org : masm_(masm), 6656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org info_(info), 6756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org scope_(info->scope()), 68b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org nesting_stack_(NULL), 69b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org loop_depth_(0), 70ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com globals_(NULL), 71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org context_(NULL), 7256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org bailout_entries_(info->HasDeoptimizationSupport() 735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ? info->function()->ast_node_count() : 0, 745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info->zone()), 75e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org back_edges_(2, info->zone()), 766d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org ic_total_count_(0) { 77e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info->IsStub()); 78000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org Initialize(); 79000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } 80000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 81000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org void Initialize(); 82b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 83b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org static bool MakeCode(CompilationInfo* info); 84b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 8556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // Encode state and pc-offset as a BitField<type, start, size>. 8656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // Only use 30 bits because we encode the result as a smi. 8756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org class StateField : public BitField<State, 0, 1> { }; 8856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org class PcField : public BitField<unsigned, 1, 30-1> { }; 89a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static const char* State2String(State state) { 91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (state) { 92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case NO_REGISTERS: return "NO_REGISTERS"; 93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case TOS_REG: return "TOS_REG"; 94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 96a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 98b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 99129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org static const int kMaxBackEdgeWeight = 127; 100129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 101b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Platform-specific code size multiplier. 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 103a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static const int kCodeSizeMultiplier = 105; 1048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org static const int kBootCodeSizeMultiplier = 100; 105129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org#elif V8_TARGET_ARCH_X64 106a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static const int kCodeSizeMultiplier = 170; 1078496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org static const int kBootCodeSizeMultiplier = 140; 108129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org#elif V8_TARGET_ARCH_ARM 109a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static const int kCodeSizeMultiplier = 149; 1108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org static const int kBootCodeSizeMultiplier = 110; 111fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#elif V8_TARGET_ARCH_ARM64 112fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// TODO(all): Copied ARM value. Check this is sensible for ARM64. 113a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static const int kCodeSizeMultiplier = 149; 1148496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org static const int kBootCodeSizeMultiplier = 110; 115129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org#elif V8_TARGET_ARCH_MIPS 116a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static const int kCodeSizeMultiplier = 149; 1178496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org static const int kBootCodeSizeMultiplier = 120; 11812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#elif V8_TARGET_ARCH_MIPS64 11912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kCodeSizeMultiplier = 149; 12012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kBootCodeSizeMultiplier = 120; 121129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org#else 122129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org#error Unsupported target architecture. 123129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org#endif 124129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 125b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org private: 126b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class Breakable; 127b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class Iteration; 12828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 1296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org class TestContext; 130b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 131b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class NestedStatement BASE_EMBEDDED { 132b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 133b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { 134b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Link into codegen's nesting stack. 135b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org previous_ = codegen->nesting_stack_; 136b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org codegen->nesting_stack_ = this; 137b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 138b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~NestedStatement() { 139b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Unlink from codegen's nesting stack. 140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(this, codegen_->nesting_stack_); 141b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org codegen_->nesting_stack_ = previous_; 142b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 143b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 144b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual Breakable* AsBreakable() { return NULL; } 145b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual Iteration* AsIteration() { return NULL; } 146b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 147b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual bool IsContinueTarget(Statement* target) { return false; } 148b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual bool IsBreakTarget(Statement* target) { return false; } 149b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1504acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Notify the statement that we are exiting it via break, continue, or 1514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // return and give it a chance to generate cleanup code. Return the 1524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // next outer statement in the nesting stack. We accumulate in 1534acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // *stack_depth the amount to drop the stack and in *context_length the 1544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // number of context chain links to unwind as we traverse the nesting 1554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // stack from an exit to its target. 1564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length) { 1574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org return previous_; 158b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 159e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 16005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org protected: 161b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org MacroAssembler* masm() { return codegen_->masm(); } 162e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 163b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org FullCodeGenerator* codegen_; 164b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org NestedStatement* previous_; 16505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org 16605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org private: 167b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DISALLOW_COPY_AND_ASSIGN(NestedStatement); 168b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 169b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 17028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // A breakable statement such as a block. 171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class Breakable : public NestedStatement { 172b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 17328a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org Breakable(FullCodeGenerator* codegen, BreakableStatement* statement) 17428a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org : NestedStatement(codegen), statement_(statement) { 17528a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org } 176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~Breakable() {} 17728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 178b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual Breakable* AsBreakable() { return this; } 17928a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org virtual bool IsBreakTarget(Statement* target) { 18028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org return statement() == target; 181b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 18228a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 18328a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org BreakableStatement* statement() { return statement_; } 18428a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org Label* break_label() { return &break_label_; } 18528a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 186b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org private: 18728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org BreakableStatement* statement_; 18828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org Label break_label_; 189b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 190b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 19128a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // An iteration statement such as a while, for, or do loop. 192b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class Iteration : public Breakable { 193b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 19428a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org Iteration(FullCodeGenerator* codegen, IterationStatement* statement) 19528a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org : Breakable(codegen, statement) { 19628a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org } 197b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~Iteration() {} 19828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 199b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual Iteration* AsIteration() { return this; } 20028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org virtual bool IsContinueTarget(Statement* target) { 20128a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org return statement() == target; 202b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 20328a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 20428a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org Label* continue_label() { return &continue_label_; } 20528a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 206b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org private: 20728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org Label continue_label_; 208b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 209b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 210486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // A nested block statement. 211486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org class NestedBlock : public Breakable { 212486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org public: 213486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org NestedBlock(FullCodeGenerator* codegen, Block* block) 214486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org : Breakable(codegen, block) { 215486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 216486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual ~NestedBlock() {} 217486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 218486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length) { 219ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (statement()->AsBlock()->scope() != NULL) { 220486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ++(*context_length); 221486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 222486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return previous_; 2233c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } 224486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org }; 225486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 22628a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // The try block of a try/catch statement. 227b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class TryCatch : public NestedStatement { 228b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 22928a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) { 23028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org } 231b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~TryCatch() {} 23228a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 2334acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length); 234b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 235b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 23628a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // The try block of a try/finally statement. 237b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class TryFinally : public NestedStatement { 238b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 23928a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org TryFinally(FullCodeGenerator* codegen, Label* finally_entry) 24028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org : NestedStatement(codegen), finally_entry_(finally_entry) { 24128a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org } 242b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~TryFinally() {} 24328a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 2444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length); 24528a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 246b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org private: 247b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label* finally_entry_; 248b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 249b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 25028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // The finally block of a try/finally statement. 251b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class Finally : public NestedStatement { 252b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 2537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org static const int kElementCount = 5; 25428a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 255b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { } 256b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~Finally() {} 25728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 2584acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length) { 25928a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org *stack_depth += kElementCount; 2604acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org return previous_; 261b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 262b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 263b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 26428a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // The body of a for/in loop. 265b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org class ForIn : public Iteration { 266b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 26728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org static const int kElementCount = 5; 26828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 26928a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org ForIn(FullCodeGenerator* codegen, ForInStatement* statement) 27028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org : Iteration(codegen, statement) { 27128a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org } 272b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~ForIn() {} 27328a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org 2744acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length) { 27528a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org *stack_depth += kElementCount; 2764acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org return previous_; 277b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 278b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org }; 279b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2804acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 28128a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org // The body of a with or catch. 2824acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org class WithOrCatch : public NestedStatement { 2834acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org public: 2844acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org explicit WithOrCatch(FullCodeGenerator* codegen) 2854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org : NestedStatement(codegen) { 2864acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 2874acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual ~WithOrCatch() {} 2884acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 2894acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org virtual NestedStatement* Exit(int* stack_depth, int* context_length) { 2904acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org ++(*context_length); 2914acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org return previous_; 2924acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 2934acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org }; 2944acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 295d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com // Type of a member function that generates inline code for a native function. 296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org typedef void (FullCodeGenerator::*InlineFunctionGenerator)(CallRuntime* expr); 297d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 298d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com static const InlineFunctionGenerator kInlineFunctionGenerators[]; 299d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 3005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // A platform-specific utility to overwrite the accumulator register 3015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // with a GC-safe value. 3025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org void ClearAccumulator(); 3035f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 30465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Determine whether or not to inline the smi case for the given 30565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // operation. 30665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org bool ShouldInlineSmiCase(Token::Value op); 30765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 308b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Helper function to convert a pure value into a test context. The value 309b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // is expected on the stack or the accumulator, depending on the platform. 310b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // See the platform-specific implementation for details. 3116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org void DoTest(Expression* condition, 3126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* if_true, 3136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* if_false, 3146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* fall_through); 3156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org void DoTest(const TestContext* context); 31665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 31765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Helper function to split control flow and avoid a branch to the 31865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // fall-through label if it is set up. 31993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 32065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org void Split(Condition cc, 321c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register lhs, 322c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const Operand& rhs, 32365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_true, 32465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_false, 32565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through); 32612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#elif V8_TARGET_ARCH_MIPS64 32712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void Split(Condition cc, 32812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Register lhs, 32912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org const Operand& rhs, 33012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Label* if_true, 33112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Label* if_false, 33212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Label* fall_through); 333c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org#else // All non-mips arch. 334c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org void Split(Condition cc, 335c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* if_true, 336c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* if_false, 337c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* fall_through); 338c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org#endif // V8_TARGET_ARCH_MIPS 339b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 340486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Load the value of a known (PARAMETER, LOCAL, or CONTEXT) variable into 341486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // a register. Emits a context chain walk if if necessary (so does 342486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // SetVar) so avoid calling both on the same variable. 343486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org void GetVar(Register destination, Variable* var); 344486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 345486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Assign to a known (PARAMETER, LOCAL, or CONTEXT) variable. If it's in 346486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // the context, the write barrier will be emitted and source, scratch0, 347486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // scratch1 will be clobbered. Emits a context chain walk if if necessary 348486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // (so does GetVar) so avoid calling both on the same variable. 349486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org void SetVar(Variable* var, 350486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Register source, 351486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Register scratch0, 352486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Register scratch1); 353486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 354486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // An operand used to read/write a stack-allocated (PARAMETER or LOCAL) 355486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // variable. Writing does not need the write barrier. 356486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand StackOperand(Variable* var); 357486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 358486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) 359486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // variable. May emit code to traverse the context chain, loading the 360486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // found context into the scratch register. Writing to this operand will 361486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // need the write barrier if location is CONTEXT. 362486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand VarOperand(Variable* var, Register scratch); 363b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 364b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void VisitForEffect(Expression* expr) { 3654a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org EffectContext context(this); 366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Visit(expr); 367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailout(expr, NO_REGISTERS); 3684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 3694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 3704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org void VisitForAccumulatorValue(Expression* expr) { 3714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AccumulatorValueContext context(this); 372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Visit(expr); 373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailout(expr, TOS_REG); 374b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 375b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org void VisitForStackValue(Expression* expr) { 3774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org StackValueContext context(this); 378c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Visit(expr); 379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailout(expr, NO_REGISTERS); 380b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 381b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 38265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org void VisitForControl(Expression* expr, 38365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_true, 38465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_false, 38565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through) { 3866d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org TestContext context(this, expr, if_true, if_false, fall_through); 387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Visit(expr); 388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // For test contexts, we prepare for bailout before branching, not at 389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the end of the entire expression. This happens as part of visiting 390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the expression. 391b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 392b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 393c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void VisitInDuplicateContext(Expression* expr); 394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 395b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void VisitDeclarations(ZoneList<Declaration*>* declarations); 3968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org void DeclareModules(Handle<FixedArray> descriptions); 397b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void DeclareGlobals(Handle<FixedArray> pairs); 3981805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org int DeclareGlobalsFlags(); 399b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Generate code to allocate all (including nested) modules and contexts. 4018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Because of recursive linking and the presence of module alias declarations, 4028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // this has to be a separate pass _before_ populating or executing any module. 4038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org void AllocateModules(ZoneList<Declaration*>* declarations); 4048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 40541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // Generate code to create an iterator result object. The "value" property is 40641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // set to a value popped from the stack, and "done" is set according to the 40741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // argument. The result object is left in the result register. 40841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org void EmitCreateIteratorResult(bool done); 40957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 41065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Try to perform a comparison as a fast inlined literal compare if 41165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // the operands allow it. Returns true if the compare operations 41265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // has been matched and all code generated; false otherwise. 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool TryLiteralCompare(CompareOperation* compare); 41465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 41504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Platform-specific code for comparing the type of a value with 41604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // a given literal string. 417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void EmitLiteralCompareTypeof(Expression* expr, 418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Expression* sub_expr, 419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<String> check); 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Platform-specific code for equality comparison with a nil-like value. 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void EmitLiteralCompareNil(CompareOperation* expr, 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Expression* sub_expr, 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NilValue nil); 42504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Bailout support. 427d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org void PrepareForBailout(Expression* node, State state); 428471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org void PrepareForBailoutForId(BailoutId id, State state); 429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 430f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Feedback slot support. The feedback vector will be cleared during gc and 431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // collected by the type-feedback oracle. 432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Handle<FixedArray> FeedbackVector() { 433a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return info_->feedback_vector(); 434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 435a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org void EnsureSlotContainsAllocationSite(int slot); 436fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Record a call's return site offset, used to rebuild the frame if the 438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // called function was inlined at the site. 439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void RecordJSReturnSite(Call* call); 440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Prepare for bailout before a test (or compare) and branch. If 442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // should_normalize, then the following comparison will not handle the 443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // canonical JS true value so we will insert a (dead) test against true at 444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the actual bailout target from the optimized code. If not 445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // should_normalize, the true and false labels are ignored. 446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void PrepareForBailoutBeforeSplit(Expression* expr, 447a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool should_normalize, 448a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label* if_true, 449a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label* if_false); 450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 451ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // If enabled, emit debug code for checking that the current context is 452ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // neither a with nor a catch context. 453ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com void EmitDebugCheckDeclarationContext(Variable* variable); 4549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 45556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // This is meant to be called at loop back edges, |back_edge_target| is 45656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // the jump target of the back edge and is used to approximate the amount 45756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // of code inside the loop. 458cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org void EmitBackEdgeBookkeeping(IterationStatement* stmt, 459cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org Label* back_edge_target); 460cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org // Record the OSR AST id corresponding to a back edge in the code. 461cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org void RecordBackEdge(BailoutId osr_ast_id); 462e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Emit a table of back edge ids, pcs and loop depths into the code stream. 463e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Return the offset of the start of the table. 464e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org unsigned EmitBackEdgeTable(); 465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4664efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org void EmitProfilingCounterDecrement(int delta); 4674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org void EmitProfilingCounterReset(); 4684efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 46941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // Emit code to pop values from the stack associated with nested statements 47041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // like try/catch, try/finally, etc, running the finallies and unwinding the 47141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // handlers as needed. 47241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org void EmitUnwindBeforeReturn(); 47341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 474b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Platform-specific return sequence 4752cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org void EmitReturnSequence(); 476b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 477b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Platform-specific code sequences for calls 478d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org void EmitCall(Call* expr, CallICState::CallType = CallICState::FUNCTION); 479a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org void EmitCallWithLoadIC(Call* expr); 480a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void EmitSuperCallWithLoadIC(Call* expr); 481a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org void EmitKeyedCallWithLoadIC(Call* expr, Expression* key); 482b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Platform-specific code for inline runtime calls. 484d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id); 485d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com 4869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com void EmitInlineRuntimeCall(CallRuntime* expr); 487145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com 488145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com#define EMIT_INLINE_RUNTIME_CALL(name, x, y) \ 489c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void Emit##name(CallRuntime* expr); 490d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL) 491145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com#undef EMIT_INLINE_RUNTIME_CALL 4929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 493ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Platform-specific code for resuming generators. 494ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org void EmitGeneratorResume(Expression *generator, 495ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Expression *value, 496ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org JSGeneratorObject::ResumeMode resume_mode); 497ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 498b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Platform-specific code for loading variables. 4999d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org void EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 500486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org TypeofState typeof_state, 501486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* slow); 502486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand ContextSlotOperandCheckExtensions(Variable* var, Label* slow); 5039d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org void EmitDynamicLookupFastCase(VariableProxy* proxy, 504486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org TypeofState typeof_state, 505486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* slow, 506486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* done); 507030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org void EmitVariableLoad(VariableProxy* proxy); 508b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org void EmitAccessor(Expression* expression); 5102c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 5119ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Expects the arguments and the function already pushed. 512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void EmitResolvePossiblyDirectEval(int arg_count); 5139ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 5149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Platform-specific support for allocating a new closure based on 5159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // the given function info. 51621b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org void EmitNewClosure(Handle<SharedFunctionInfo> info, bool pretenure); 5179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 518b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Platform-specific support for compiling assignments. 519b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 520b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Load a value from a named property. 521b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // The receiver is left on the stack by the IC. 522b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void EmitNamedPropertyLoad(Property* expr); 523b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 524a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void EmitNamedSuperPropertyLoad(Property* expr); 525a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 526b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Load a value from a keyed property. 527b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // The receiver and the key is left on the stack by the IC. 528b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void EmitKeyedPropertyLoad(Property* expr); 529b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 530b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Apply the compound assignment operator. Expects the left operand on top 531b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // of the stack and the right one in the accumulator. 5328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org void EmitBinaryOp(BinaryOperation* expr, 5338e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org Token::Value op, 53465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org OverwriteMode mode); 535b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 536d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Helper functions for generating inlined smi code for certain 537d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // binary operations. 5388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org void EmitInlineSmiBinaryOp(BinaryOperation* expr, 539d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Token::Value op, 540d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org OverwriteMode mode, 541d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Expression* left, 5429ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Expression* right); 543d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 5449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Assign to the given expression as if via '='. The right-hand-side value 5459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // is expected in the accumulator. 546be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org void EmitAssignment(Expression* expr); 5479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Complete a variable assignment. The right-hand-side value is expected 549b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // in the accumulator. 5509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com void EmitVariableAssignment(Variable* var, 5514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Token::Value op); 552b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 553f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Helper functions to EmitVariableAssignment 554f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitStoreToStackLocalOrContextSlot(Variable* var, 555f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MemOperand location); 556f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 557b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Complete a named property assignment. The receiver is expected on top 558b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // of the stack and the right-hand-side value in the accumulator. 559b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void EmitNamedPropertyAssignment(Assignment* expr); 560b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 561b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Complete a keyed property assignment. The receiver and key are 562b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // expected on top of the stack and the right-hand-side value in the 563b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // accumulator. 564b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void EmitKeyedPropertyAssignment(Assignment* expr); 565b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 566a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void EmitLoadHomeObject(SuperReference* expr); 567a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 568f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org void CallIC(Handle<Code> code, 569471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId id = TypeFeedbackId::None()); 570f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 5719cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org void CallLoadIC(ContextualMode mode, 5729cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org TypeFeedbackId id = TypeFeedbackId::None()); 573f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None()); 5749cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 575b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void SetFunctionPosition(FunctionLiteral* fun); 576b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void SetReturnPosition(FunctionLiteral* fun); 577b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void SetStatementPosition(Statement* stmt); 578a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org void SetExpressionPosition(Expression* expr); 579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void SetSourcePosition(int pos); 580b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 581b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Non-local control flow support. 582b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void EnterFinallyBlock(); 583b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void ExitFinallyBlock(); 584b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 585b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Loop nesting counter. 586b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int loop_depth() { return loop_depth_; } 587b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void increment_loop_depth() { loop_depth_++; } 588b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void decrement_loop_depth() { 589e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(loop_depth_ > 0); 590b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org loop_depth_--; 591b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 592b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 593b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org MacroAssembler* masm() { return masm_; } 5945c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org class ExpressionContext; 5964a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org const ExpressionContext* context() { return context_; } 5974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org void set_new_context(const ExpressionContext* context) { context_ = context; } 5984a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 5995c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Script> script() { return info_->script(); } 6005c838251403b0be9a882540f1922577abba4c872ager@chromium.org bool is_eval() { return info_->is_eval(); } 6011805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org bool is_native() { return info_->is_native(); } 602486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode() { return function()->strict_mode(); } 6035c838251403b0be9a882540f1922577abba4c872ager@chromium.org FunctionLiteral* function() { return info_->function(); } 6044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* scope() { return scope_; } 6055c838251403b0be9a882540f1922577abba4c872ager@chromium.org 606b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org static Register result_register(); 607b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org static Register context_register(); 608b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 609b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Set fields in the stack frame. Offsets are the frame pointer relative 610b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // offsets defined in, e.g., StandardFrameConstants. 611b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void StoreToFrameField(int frame_offset, Register value); 612b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 613b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Load a value from the current context. Indices are defined as an enum 614b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // in v8::internal::Context. 615b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void LoadContextField(Register dst, int context_index); 616b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 6173cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Push the function argument for the runtime functions PushWithContext 6183cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // and PushCatchContext. 6193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org void PushFunctionArgumentForContextAllocation(); 6203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 621b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // AST node visit functions. 622b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define DECLARE_VISIT(type) virtual void Visit##type(type* node); 623b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org AST_NODE_LIST(DECLARE_VISIT) 624b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#undef DECLARE_VISIT 6258e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 626d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org void VisitComma(BinaryOperation* expr); 627d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org void VisitLogicalExpression(BinaryOperation* expr); 628d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org void VisitArithmeticExpression(BinaryOperation* expr); 629b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 6304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org void VisitForTypeofValue(Expression* expr); 63165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 632f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org void Generate(); 633f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org void PopulateDeoptimizationData(Handle<Code> code); 634f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org void PopulateTypeFeedbackInfo(Handle<Code> code); 635f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 636f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org Handle<FixedArray> handler_table() { return handler_table_; } 637f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 638a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct BailoutEntry { 639471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org BailoutId id; 640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org unsigned pc_and_state; 641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 642b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 643e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct BackEdgeEntry { 644e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org BailoutId id; 645e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org unsigned pc; 646ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org uint32_t loop_depth; 647e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org }; 648e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 649a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ExpressionContext BASE_EMBEDDED { 6504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org public: 6514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org explicit ExpressionContext(FullCodeGenerator* codegen) 6524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { 6534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org codegen->set_new_context(this); 6544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 6554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6564a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual ~ExpressionContext() { 6574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org codegen_->set_new_context(old_); 6584a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 6594a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 660ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate() const { return codegen_->isolate(); } 661ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 6624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Convert constant control flow (true or false) to the result expected for 6634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // this expression context. 6644a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(bool flag) const = 0; 6654a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 666486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Emit code to convert a pure value (in a register, known variable 667486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // location, as a literal, or on top of the stack) into the result 668486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // expected according to this expression context. 6694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Register reg) const = 0; 670486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual void Plug(Variable* var) const = 0; 6714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Handle<Object> lit) const = 0; 6724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Heap::RootListIndex index) const = 0; 6734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PlugTOS() const = 0; 6744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Emit code to convert pure control flow to a pair of unbound labels into 6764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // the result expected according to this expression context. The 677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // implementation will bind both labels unless it's a TestContext, which 678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // won't bind them at this point. 6794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Label* materialize_true, 6804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false) const = 0; 6814a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Emit code to discard count elements from the top of stack, then convert 6834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // a pure value into the result expected according to this expression 6844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // context. 6854a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void DropAndPlug(int count, Register reg) const = 0; 6864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Set up branch labels for a test expression. The three Label** parameters 6884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // are output parameters. 6894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PrepareTest(Label* materialize_true, 6904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false, 6914a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_true, 6924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_false, 6934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** fall_through) const = 0; 6944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6952efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Returns true if we are evaluating only for side effects (i.e. if the 6962efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // result will be discarded). 6974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual bool IsEffect() const { return false; } 6984a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 699d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Returns true if we are evaluating for the value (in accu/on stack). 700d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org virtual bool IsAccumulatorValue() const { return false; } 701d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org virtual bool IsStackValue() const { return false; } 702d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 7034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Returns true if we are branching on the value rather than materializing 704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // it. Only used for asserts. 7054a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual bool IsTest() const { return false; } 7064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7074a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org protected: 7084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org FullCodeGenerator* codegen() const { return codegen_; } 7094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org MacroAssembler* masm() const { return masm_; } 7104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org MacroAssembler* masm_; 7114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7124a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org private: 7134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org const ExpressionContext* old_; 7144a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org FullCodeGenerator* codegen_; 7154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org }; 7164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org class AccumulatorValueContext : public ExpressionContext { 7184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org public: 7194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org explicit AccumulatorValueContext(FullCodeGenerator* codegen) 720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : ExpressionContext(codegen) { } 7214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7224a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(bool flag) const; 7234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Register reg) const; 7244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Label* materialize_true, Label* materialize_false) const; 725486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual void Plug(Variable* var) const; 7264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Handle<Object> lit) const; 7274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Heap::RootListIndex) const; 7284a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PlugTOS() const; 7294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void DropAndPlug(int count, Register reg) const; 7304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PrepareTest(Label* materialize_true, 7314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false, 7324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_true, 7334a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_false, 7344a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** fall_through) const; 735d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org virtual bool IsAccumulatorValue() const { return true; } 7364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org }; 7374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org class StackValueContext : public ExpressionContext { 7394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org public: 7404a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org explicit StackValueContext(FullCodeGenerator* codegen) 741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : ExpressionContext(codegen) { } 7424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(bool flag) const; 7444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Register reg) const; 7454a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Label* materialize_true, Label* materialize_false) const; 746486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual void Plug(Variable* var) const; 7474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Handle<Object> lit) const; 7484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Heap::RootListIndex) const; 7494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PlugTOS() const; 7504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void DropAndPlug(int count, Register reg) const; 7514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PrepareTest(Label* materialize_true, 7524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false, 7534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_true, 7544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_false, 7554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** fall_through) const; 756d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org virtual bool IsStackValue() const { return true; } 7574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org }; 7584a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7594a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org class TestContext : public ExpressionContext { 7604a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org public: 7616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org TestContext(FullCodeGenerator* codegen, 7626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Expression* condition, 7636d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* true_label, 7646d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* false_label, 7656d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* fall_through) 7664a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org : ExpressionContext(codegen), 7676d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org condition_(condition), 7684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org true_label_(true_label), 7694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org false_label_(false_label), 770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org fall_through_(fall_through) { } 7714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 772b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org static const TestContext* cast(const ExpressionContext* context) { 773e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(context->IsTest()); 774b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org return reinterpret_cast<const TestContext*>(context); 775b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org } 776b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org 7776d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Expression* condition() const { return condition_; } 778b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org Label* true_label() const { return true_label_; } 779b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org Label* false_label() const { return false_label_; } 780b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org Label* fall_through() const { return fall_through_; } 781b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org 7824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(bool flag) const; 7834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Register reg) const; 7844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Label* materialize_true, Label* materialize_false) const; 785486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual void Plug(Variable* var) const; 7864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Handle<Object> lit) const; 7874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Heap::RootListIndex) const; 7884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PlugTOS() const; 7894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void DropAndPlug(int count, Register reg) const; 7904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PrepareTest(Label* materialize_true, 7914a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false, 7924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_true, 7934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_false, 7944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** fall_through) const; 7954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual bool IsTest() const { return true; } 7964a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org private: 7986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Expression* condition_; 7994a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* true_label_; 8004a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* false_label_; 8014a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* fall_through_; 8024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org }; 8034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 8044a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org class EffectContext : public ExpressionContext { 8054a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org public: 8064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org explicit EffectContext(FullCodeGenerator* codegen) 807c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : ExpressionContext(codegen) { } 8084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 8094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(bool flag) const; 8104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Register reg) const; 8114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Label* materialize_true, Label* materialize_false) const; 812486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org virtual void Plug(Variable* var) const; 8134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Handle<Object> lit) const; 8144a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void Plug(Heap::RootListIndex) const; 8154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PlugTOS() const; 8164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void DropAndPlug(int count, Register reg) const; 8174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual void PrepareTest(Label* materialize_true, 8184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false, 8194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_true, 8204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** if_false, 8214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label** fall_through) const; 8224a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org virtual bool IsEffect() const { return true; } 8234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org }; 8244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org MacroAssembler* masm_; 826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CompilationInfo* info_; 8274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* scope_; 828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label return_label_; 829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org NestedStatement* nesting_stack_; 830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int loop_depth_; 831ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ZoneList<Handle<Object> >* globals_; 8328e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Handle<FixedArray> modules_; 8338e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org int module_index_; 8344a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org const ExpressionContext* context_; 835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ZoneList<BailoutEntry> bailout_entries_; 836e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ZoneList<BackEdgeEntry> back_edges_; 837f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org int ic_total_count_; 83804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Handle<FixedArray> handler_table_; 83941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> profiling_counter_; 840000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org bool generate_debug_code_; 841b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 842b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org friend class NestedStatement; 843b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 845b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); 846b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}; 847b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 848b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 8492c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org// A map from property names to getter/setter pairs allocated in the zone. 8502c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgclass AccessorTable: public TemplateHashMap<Literal, 8512c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ObjectLiteral::Accessors, 852400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org ZoneAllocationPolicy> { 8532c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org public: 8542c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org explicit AccessorTable(Zone* zone) : 855400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org TemplateHashMap<Literal, ObjectLiteral::Accessors, 8567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneAllocationPolicy>(Literal::Match, 8577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneAllocationPolicy(zone)), 8582c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org zone_(zone) { } 8592c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 8602c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Iterator lookup(Literal* literal) { 8617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Iterator it = find(literal, true, ZoneAllocationPolicy(zone_)); 8622c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (it->second == NULL) it->second = new(zone_) ObjectLiteral::Accessors(); 8632c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org return it; 8642c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 8652c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 8662c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org private: 8672c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Zone* zone_; 8682c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}; 8692c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 8702c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 871528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgclass BackEdgeTable { 872528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org public: 873528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org BackEdgeTable(Code* code, DisallowHeapAllocation* required) { 874e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code->kind() == Code::FUNCTION); 875528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org instruction_start_ = code->instruction_start(); 876528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address table_address = instruction_start_ + code->back_edge_table_offset(); 877528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org length_ = Memory::uint32_at(table_address); 878528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org start_ = table_address + kTableLengthSize; 879528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 880528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org uint32_t length() { return length_; } 882528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 883528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org BailoutId ast_id(uint32_t index) { 884528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return BailoutId(static_cast<int>( 885528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Memory::uint32_at(entry_at(index) + kAstIdOffset))); 886528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 888528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org uint32_t loop_depth(uint32_t index) { 889528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return Memory::uint32_at(entry_at(index) + kLoopDepthOffset); 890528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 891528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 892528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org uint32_t pc_offset(uint32_t index) { 893528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return Memory::uint32_at(entry_at(index) + kPcOffsetOffset); 894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 895528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 896528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address pc(uint32_t index) { 897528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return instruction_start_ + pc_offset(index); 898528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 899528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 900528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org enum BackEdgeState { 901528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org INTERRUPT, 9028e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ON_STACK_REPLACEMENT, 9038e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org OSR_AFTER_STACK_CHECK 904528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org }; 905528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 90608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org // Increase allowed loop nesting level by one and patch those matching loops. 90708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org static void Patch(Isolate* isolate, Code* unoptimized_code); 908528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 9098e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Patch the back edge to the target state, provided the correct callee. 910528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static void PatchAt(Code* unoptimized_code, 9118e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address pc, 9128e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org BackEdgeState target_state, 913528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* replacement_code); 914528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 9158e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Change all patched back edges back to normal interrupts. 916528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static void Revert(Isolate* isolate, 917528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* unoptimized_code); 918528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 9198e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Change a back edge patched for on-stack replacement to perform a 9208e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // stack check first. 9214954674151afa960af66efb4831df06bde727333yangguo@chromium.org static void AddStackCheck(Handle<Code> code, uint32_t pc_offset); 922528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 9234954674151afa960af66efb4831df06bde727333yangguo@chromium.org // Revert the patch by AddStackCheck. 9244954674151afa960af66efb4831df06bde727333yangguo@chromium.org static void RemoveStackCheck(Handle<Code> code, uint32_t pc_offset); 9258e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 9268e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Return the current patch state of the back edge. 927528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static BackEdgeState GetBackEdgeState(Isolate* isolate, 928528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* unoptimized_code, 929528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address pc_after); 930528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 9318e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#ifdef DEBUG 932528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Verify that all back edges of a certain loop depth are patched. 93308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org static bool Verify(Isolate* isolate, Code* unoptimized_code); 934528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#endif // DEBUG 935528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 936528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org private: 937528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address entry_at(uint32_t index) { 938e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < length_); 939528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return start_ + index * kEntrySize; 940528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 941528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 942528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static const int kTableLengthSize = kIntSize; 943528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static const int kAstIdOffset = 0 * kIntSize; 944528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static const int kPcOffsetOffset = 1 * kIntSize; 945528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static const int kLoopDepthOffset = 2 * kIntSize; 946528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org static const int kEntrySize = 3 * kIntSize; 947528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 948528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address start_; 949528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address instruction_start_; 950528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org uint32_t length_; 951528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}; 952528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 953528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 954b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} } // namespace v8::internal 955b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 956b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif // V8_FULL_CODEGEN_H_ 957