Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_MACRO_ASSEMBLER_H_
      6 #define V8_MACRO_ASSEMBLER_H_
      7 
      8 
      9 // Helper types to make boolean flag easier to read at call-site.
     10 enum InvokeFlag {
     11   CALL_FUNCTION,
     12   JUMP_FUNCTION
     13 };
     14 
     15 
     16 // Flags used for the AllocateInNewSpace functions.
     17 enum AllocationFlags {
     18   // No special flags.
     19   NO_ALLOCATION_FLAGS = 0,
     20   // Return the pointer to the allocated already tagged as a heap object.
     21   TAG_OBJECT = 1 << 0,
     22   // The content of the result register already contains the allocation top in
     23   // new space.
     24   RESULT_CONTAINS_TOP = 1 << 1,
     25   // Specify that the requested size of the space to allocate is specified in
     26   // words instead of bytes.
     27   SIZE_IN_WORDS = 1 << 2,
     28   // Align the allocation to a multiple of kDoubleSize
     29   DOUBLE_ALIGNMENT = 1 << 3,
     30   // Directly allocate in old pointer space
     31   PRETENURE_OLD_POINTER_SPACE = 1 << 4,
     32   // Directly allocate in old data space
     33   PRETENURE_OLD_DATA_SPACE = 1 << 5
     34 };
     35 
     36 
     37 // Invalid depth in prototype chain.
     38 const int kInvalidProtoDepth = -1;
     39 
     40 #if V8_TARGET_ARCH_IA32
     41 #include "src/assembler.h"
     42 #include "src/ia32/assembler-ia32.h"
     43 #include "src/ia32/assembler-ia32-inl.h"
     44 #include "src/code.h"  // must be after assembler_*.h
     45 #include "src/ia32/macro-assembler-ia32.h"
     46 #elif V8_TARGET_ARCH_X64
     47 #include "src/assembler.h"
     48 #include "src/x64/assembler-x64.h"
     49 #include "src/x64/assembler-x64-inl.h"
     50 #include "src/code.h"  // must be after assembler_*.h
     51 #include "src/x64/macro-assembler-x64.h"
     52 #elif V8_TARGET_ARCH_ARM64
     53 #include "src/arm64/constants-arm64.h"
     54 #include "src/assembler.h"
     55 #include "src/arm64/assembler-arm64.h"
     56 #include "src/arm64/assembler-arm64-inl.h"
     57 #include "src/code.h"  // must be after assembler_*.h
     58 #include "src/arm64/macro-assembler-arm64.h"
     59 #include "src/arm64/macro-assembler-arm64-inl.h"
     60 #elif V8_TARGET_ARCH_ARM
     61 #include "src/arm/constants-arm.h"
     62 #include "src/assembler.h"
     63 #include "src/arm/assembler-arm.h"
     64 #include "src/arm/assembler-arm-inl.h"
     65 #include "src/code.h"  // must be after assembler_*.h
     66 #include "src/arm/macro-assembler-arm.h"
     67 #elif V8_TARGET_ARCH_MIPS
     68 #include "src/mips/constants-mips.h"
     69 #include "src/assembler.h"
     70 #include "src/mips/assembler-mips.h"
     71 #include "src/mips/assembler-mips-inl.h"
     72 #include "src/code.h"  // must be after assembler_*.h
     73 #include "src/mips/macro-assembler-mips.h"
     74 #elif V8_TARGET_ARCH_X87
     75 #include "src/assembler.h"
     76 #include "src/x87/assembler-x87.h"
     77 #include "src/x87/assembler-x87-inl.h"
     78 #include "src/code.h"  // must be after assembler_*.h
     79 #include "src/x87/macro-assembler-x87.h"
     80 #else
     81 #error Unsupported target architecture.
     82 #endif
     83 
     84 namespace v8 {
     85 namespace internal {
     86 
     87 class FrameScope {
     88  public:
     89   explicit FrameScope(MacroAssembler* masm, StackFrame::Type type)
     90       : masm_(masm), type_(type), old_has_frame_(masm->has_frame()) {
     91     masm->set_has_frame(true);
     92     if (type != StackFrame::MANUAL && type_ != StackFrame::NONE) {
     93       masm->EnterFrame(type);
     94     }
     95   }
     96 
     97   ~FrameScope() {
     98     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
     99       masm_->LeaveFrame(type_);
    100     }
    101     masm_->set_has_frame(old_has_frame_);
    102   }
    103 
    104   // Normally we generate the leave-frame code when this object goes
    105   // out of scope.  Sometimes we may need to generate the code somewhere else
    106   // in addition.  Calling this will achieve that, but the object stays in
    107   // scope, the MacroAssembler is still marked as being in a frame scope, and
    108   // the code will be generated again when it goes out of scope.
    109   void GenerateLeaveFrame() {
    110     ASSERT(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
    111     masm_->LeaveFrame(type_);
    112   }
    113 
    114  private:
    115   MacroAssembler* masm_;
    116   StackFrame::Type type_;
    117   bool old_has_frame_;
    118 };
    119 
    120 
    121 class AllowExternalCallThatCantCauseGC: public FrameScope {
    122  public:
    123   explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
    124       : FrameScope(masm, StackFrame::NONE) { }
    125 };
    126 
    127 
    128 class NoCurrentFrameScope {
    129  public:
    130   explicit NoCurrentFrameScope(MacroAssembler* masm)
    131       : masm_(masm), saved_(masm->has_frame()) {
    132     masm->set_has_frame(false);
    133   }
    134 
    135   ~NoCurrentFrameScope() {
    136     masm_->set_has_frame(saved_);
    137   }
    138 
    139  private:
    140   MacroAssembler* masm_;
    141   bool saved_;
    142 };
    143 
    144 
    145 // Support for "structured" code comments.
    146 #ifdef DEBUG
    147 
    148 class Comment {
    149  public:
    150   Comment(MacroAssembler* masm, const char* msg);
    151   ~Comment();
    152 
    153  private:
    154   MacroAssembler* masm_;
    155   const char* msg_;
    156 };
    157 
    158 #else
    159 
    160 class Comment {
    161  public:
    162   Comment(MacroAssembler*, const char*)  {}
    163 };
    164 
    165 #endif  // DEBUG
    166 
    167 
    168 class AllocationUtils {
    169  public:
    170   static ExternalReference GetAllocationTopReference(
    171       Isolate* isolate, AllocationFlags flags) {
    172     if ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) {
    173       return ExternalReference::old_pointer_space_allocation_top_address(
    174           isolate);
    175     } else if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
    176       return ExternalReference::old_data_space_allocation_top_address(isolate);
    177     }
    178     return ExternalReference::new_space_allocation_top_address(isolate);
    179   }
    180 
    181 
    182   static ExternalReference GetAllocationLimitReference(
    183       Isolate* isolate, AllocationFlags flags) {
    184     if ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) {
    185       return ExternalReference::old_pointer_space_allocation_limit_address(
    186           isolate);
    187     } else if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
    188       return ExternalReference::old_data_space_allocation_limit_address(
    189           isolate);
    190     }
    191     return ExternalReference::new_space_allocation_limit_address(isolate);
    192   }
    193 };
    194 
    195 
    196 } }  // namespace v8::internal
    197 
    198 #endif  // V8_MACRO_ASSEMBLER_H_
    199