Home | History | Annotate | Download | only in mips
      1 // Copyright 2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 
     29 #ifndef V8_MIPS_CODEGEN_MIPS_H_
     30 #define V8_MIPS_CODEGEN_MIPS_H_
     31 
     32 namespace v8 {
     33 namespace internal {
     34 
     35 // Forward declarations
     36 class CompilationInfo;
     37 class DeferredCode;
     38 class RegisterAllocator;
     39 class RegisterFile;
     40 
     41 enum InitState { CONST_INIT, NOT_CONST_INIT };
     42 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
     43 
     44 
     45 // -------------------------------------------------------------------------
     46 // Code generation state
     47 
     48 // The state is passed down the AST by the code generator (and back up, in
     49 // the form of the state of the label pair).  It is threaded through the
     50 // call stack.  Constructing a state implicitly pushes it on the owning code
     51 // generator's stack of states, and destroying one implicitly pops it.
     52 
     53 class CodeGenState BASE_EMBEDDED {
     54  public:
     55   // Create an initial code generator state.  Destroying the initial state
     56   // leaves the code generator with a NULL state.
     57   explicit CodeGenState(CodeGenerator* owner);
     58 
     59   // Create a code generator state based on a code generator's current
     60   // state.  The new state has its own typeof state and pair of branch
     61   // labels.
     62   CodeGenState(CodeGenerator* owner,
     63                JumpTarget* true_target,
     64                JumpTarget* false_target);
     65 
     66   // Destroy a code generator state and restore the owning code generator's
     67   // previous state.
     68   ~CodeGenState();
     69 
     70   TypeofState typeof_state() const { return typeof_state_; }
     71   JumpTarget* true_target() const { return true_target_; }
     72   JumpTarget* false_target() const { return false_target_; }
     73 
     74  private:
     75   // The owning code generator.
     76   CodeGenerator* owner_;
     77 
     78   // A flag indicating whether we are compiling the immediate subexpression
     79   // of a typeof expression.
     80   TypeofState typeof_state_;
     81 
     82   JumpTarget* true_target_;
     83   JumpTarget* false_target_;
     84 
     85   // The previous state of the owning code generator, restored when
     86   // this state is destroyed.
     87   CodeGenState* previous_;
     88 };
     89 
     90 
     91 
     92 // -------------------------------------------------------------------------
     93 // CodeGenerator
     94 
     95 class CodeGenerator: public AstVisitor {
     96  public:
     97   // Compilation mode.  Either the compiler is used as the primary
     98   // compiler and needs to setup everything or the compiler is used as
     99   // the secondary compiler for split compilation and has to handle
    100   // bailouts.
    101   enum Mode {
    102     PRIMARY,
    103     SECONDARY
    104   };
    105 
    106   // Takes a function literal, generates code for it. This function should only
    107   // be called by compiler.cc.
    108   static Handle<Code> MakeCode(CompilationInfo* info);
    109 
    110   // Printing of AST, etc. as requested by flags.
    111   static void MakeCodePrologue(CompilationInfo* info);
    112 
    113   // Allocate and install the code.
    114   static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
    115                                        Code::Flags flags,
    116                                        CompilationInfo* info);
    117 
    118 #ifdef ENABLE_LOGGING_AND_PROFILING
    119   static bool ShouldGenerateLog(Expression* type);
    120 #endif
    121 
    122   static void SetFunctionInfo(Handle<JSFunction> fun,
    123                               FunctionLiteral* lit,
    124                               bool is_toplevel,
    125                               Handle<Script> script);
    126 
    127   static void RecordPositions(MacroAssembler* masm, int pos);
    128 
    129   // Accessors
    130   MacroAssembler* masm() { return masm_; }
    131   VirtualFrame* frame() const { return frame_; }
    132   inline Handle<Script> script();
    133 
    134   bool has_valid_frame() const { return frame_ != NULL; }
    135 
    136   // Set the virtual frame to be new_frame, with non-frame register
    137   // reference counts given by non_frame_registers.  The non-frame
    138   // register reference counts of the old frame are returned in
    139   // non_frame_registers.
    140   void SetFrame(VirtualFrame* new_frame, RegisterFile* non_frame_registers);
    141 
    142   void DeleteFrame();
    143 
    144   RegisterAllocator* allocator() const { return allocator_; }
    145 
    146   CodeGenState* state() { return state_; }
    147   void set_state(CodeGenState* state) { state_ = state; }
    148 
    149   void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
    150 
    151   static const int kUnknownIntValue = -1;
    152 
    153   // Number of instructions used for the JS return sequence. The constant is
    154   // used by the debugger to patch the JS return sequence.
    155   static const int kJSReturnSequenceLength = 6;
    156 
    157  private:
    158   // Construction/Destruction.
    159   explicit CodeGenerator(MacroAssembler* masm);
    160   virtual ~CodeGenerator() { delete masm_; }
    161 
    162   // Accessors.
    163   inline bool is_eval();
    164   Scope* scope() const { return scope_; }
    165 
    166   // Generating deferred code.
    167   void ProcessDeferred();
    168 
    169   // State
    170   bool has_cc() const  { return cc_reg_ != cc_always; }
    171   TypeofState typeof_state() const { return state_->typeof_state(); }
    172   JumpTarget* true_target() const  { return state_->true_target(); }
    173   JumpTarget* false_target() const  { return state_->false_target(); }
    174 
    175   // We don't track loop nesting level on mips yet.
    176   int loop_nesting() const { return 0; }
    177 
    178   // Node visitors.
    179   void VisitStatements(ZoneList<Statement*>* statements);
    180 
    181 #define DEF_VISIT(type) \
    182   void Visit##type(type* node);
    183   AST_NODE_LIST(DEF_VISIT)
    184 #undef DEF_VISIT
    185 
    186   // Main code generation function
    187   void Generate(CompilationInfo* info, Mode mode);
    188 
    189   struct InlineRuntimeLUT {
    190     void (CodeGenerator::*method)(ZoneList<Expression*>*);
    191     const char* name;
    192   };
    193 
    194   static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
    195   bool CheckForInlineRuntimeCall(CallRuntime* node);
    196   static bool PatchInlineRuntimeEntry(Handle<String> name,
    197                                       const InlineRuntimeLUT& new_entry,
    198                                       InlineRuntimeLUT* old_entry);
    199 
    200   static Handle<Code> ComputeLazyCompile(int argc);
    201   void ProcessDeclarations(ZoneList<Declaration*>* declarations);
    202 
    203   Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop);
    204 
    205   // Declare global variables and functions in the given array of
    206   // name/value pairs.
    207   void DeclareGlobals(Handle<FixedArray> pairs);
    208 
    209   // Support for type checks.
    210   void GenerateIsSmi(ZoneList<Expression*>* args);
    211   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
    212   void GenerateIsArray(ZoneList<Expression*>* args);
    213   void GenerateIsRegExp(ZoneList<Expression*>* args);
    214 
    215   // Support for construct call checks.
    216   void GenerateIsConstructCall(ZoneList<Expression*>* args);
    217 
    218   // Support for arguments.length and arguments[?].
    219   void GenerateArgumentsLength(ZoneList<Expression*>* args);
    220   void GenerateArgumentsAccess(ZoneList<Expression*>* args);
    221 
    222   // Support for accessing the class and value fields of an object.
    223   void GenerateClassOf(ZoneList<Expression*>* args);
    224   void GenerateValueOf(ZoneList<Expression*>* args);
    225   void GenerateSetValueOf(ZoneList<Expression*>* args);
    226 
    227   // Fast support for charCodeAt(n).
    228   void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
    229 
    230   // Fast support for object equality testing.
    231   void GenerateObjectEquals(ZoneList<Expression*>* args);
    232 
    233   void GenerateLog(ZoneList<Expression*>* args);
    234 
    235   // Fast support for Math.random().
    236   void GenerateRandomPositiveSmi(ZoneList<Expression*>* args);
    237 
    238   void GenerateIsObject(ZoneList<Expression*>* args);
    239   void GenerateIsFunction(ZoneList<Expression*>* args);
    240   void GenerateIsUndetectableObject(ZoneList<Expression*>* args);
    241   void GenerateStringAdd(ZoneList<Expression*>* args);
    242   void GenerateSubString(ZoneList<Expression*>* args);
    243   void GenerateStringCompare(ZoneList<Expression*>* args);
    244   void GenerateRegExpExec(ZoneList<Expression*>* args);
    245   void GenerateNumberToString(ZoneList<Expression*>* args);
    246 
    247 
    248   // Fast support for Math.sin and Math.cos.
    249   inline void GenerateMathSin(ZoneList<Expression*>* args);
    250   inline void GenerateMathCos(ZoneList<Expression*>* args);
    251 
    252   // Simple condition analysis.
    253   enum ConditionAnalysis {
    254     ALWAYS_TRUE,
    255     ALWAYS_FALSE,
    256     DONT_KNOW
    257   };
    258   ConditionAnalysis AnalyzeCondition(Expression* cond);
    259 
    260   // Methods used to indicate which source code is generated for. Source
    261   // positions are collected by the assembler and emitted with the relocation
    262   // information.
    263   void CodeForFunctionPosition(FunctionLiteral* fun);
    264   void CodeForReturnPosition(FunctionLiteral* fun);
    265   void CodeForStatementPosition(Statement* node);
    266   void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
    267   void CodeForSourcePosition(int pos);
    268 
    269 #ifdef DEBUG
    270   // True if the registers are valid for entry to a block.
    271   bool HasValidEntryRegisters();
    272 #endif
    273 
    274   bool is_eval_;  // Tells whether code is generated for eval.
    275 
    276   Handle<Script> script_;
    277   List<DeferredCode*> deferred_;
    278 
    279   // Assembler
    280   MacroAssembler* masm_;  // to generate code
    281 
    282   CompilationInfo* info_;
    283 
    284   // Code generation state
    285   Scope* scope_;
    286   VirtualFrame* frame_;
    287   RegisterAllocator* allocator_;
    288   Condition cc_reg_;
    289   CodeGenState* state_;
    290 
    291   // Jump targets
    292   BreakTarget function_return_;
    293 
    294   // True if the function return is shadowed (ie, jumping to the target
    295   // function_return_ does not jump to the true function return, but rather
    296   // to some unlinking code).
    297   bool function_return_is_shadowed_;
    298 
    299   static InlineRuntimeLUT kInlineRuntimeLUT[];
    300 
    301   friend class VirtualFrame;
    302   friend class JumpTarget;
    303   friend class Reference;
    304   friend class FastCodeGenerator;
    305   friend class FullCodeGenSyntaxChecker;
    306 
    307   DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
    308 };
    309 
    310 
    311 } }  // namespace v8::internal
    312 
    313 #endif  // V8_MIPS_CODEGEN_MIPS_H_
    314