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"  // NOLINT, 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"  // NOLINT, 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"  // NOLINT
     56 #include "src/arm64/assembler-arm64-inl.h"
     57 #include "src/code.h"  // NOLINT, must be after assembler_*.h
     58 #include "src/arm64/macro-assembler-arm64.h"  // NOLINT
     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"  // NOLINT
     64 #include "src/arm/assembler-arm-inl.h"
     65 #include "src/code.h"                     // NOLINT, must be after assembler_*.h
     66 #include "src/arm/macro-assembler-arm.h"  // NOLINT
     67 #elif V8_TARGET_ARCH_MIPS
     68 #include "src/mips/constants-mips.h"
     69 #include "src/assembler.h"            // NOLINT
     70 #include "src/mips/assembler-mips.h"  // NOLINT
     71 #include "src/mips/assembler-mips-inl.h"
     72 #include "src/code.h"  // NOLINT, must be after assembler_*.h
     73 #include "src/mips/macro-assembler-mips.h"
     74 #elif V8_TARGET_ARCH_MIPS64
     75 #include "src/mips64/constants-mips64.h"
     76 #include "src/assembler.h"                // NOLINT
     77 #include "src/mips64/assembler-mips64.h"  // NOLINT
     78 #include "src/mips64/assembler-mips64-inl.h"
     79 #include "src/code.h"  // NOLINT, must be after assembler_*.h
     80 #include "src/mips64/macro-assembler-mips64.h"
     81 #elif V8_TARGET_ARCH_X87
     82 #include "src/assembler.h"
     83 #include "src/x87/assembler-x87.h"
     84 #include "src/x87/assembler-x87-inl.h"
     85 #include "src/code.h"  // NOLINT, must be after assembler_*.h
     86 #include "src/x87/macro-assembler-x87.h"
     87 #else
     88 #error Unsupported target architecture.
     89 #endif
     90 
     91 namespace v8 {
     92 namespace internal {
     93 
     94 class FrameScope {
     95  public:
     96   explicit FrameScope(MacroAssembler* masm, StackFrame::Type type)
     97       : masm_(masm), type_(type), old_has_frame_(masm->has_frame()) {
     98     masm->set_has_frame(true);
     99     if (type != StackFrame::MANUAL && type_ != StackFrame::NONE) {
    100       masm->EnterFrame(type);
    101     }
    102   }
    103 
    104   ~FrameScope() {
    105     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
    106       masm_->LeaveFrame(type_);
    107     }
    108     masm_->set_has_frame(old_has_frame_);
    109   }
    110 
    111   // Normally we generate the leave-frame code when this object goes
    112   // out of scope.  Sometimes we may need to generate the code somewhere else
    113   // in addition.  Calling this will achieve that, but the object stays in
    114   // scope, the MacroAssembler is still marked as being in a frame scope, and
    115   // the code will be generated again when it goes out of scope.
    116   void GenerateLeaveFrame() {
    117     DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
    118     masm_->LeaveFrame(type_);
    119   }
    120 
    121  private:
    122   MacroAssembler* masm_;
    123   StackFrame::Type type_;
    124   bool old_has_frame_;
    125 };
    126 
    127 
    128 class AllowExternalCallThatCantCauseGC: public FrameScope {
    129  public:
    130   explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
    131       : FrameScope(masm, StackFrame::NONE) { }
    132 };
    133 
    134 
    135 class NoCurrentFrameScope {
    136  public:
    137   explicit NoCurrentFrameScope(MacroAssembler* masm)
    138       : masm_(masm), saved_(masm->has_frame()) {
    139     masm->set_has_frame(false);
    140   }
    141 
    142   ~NoCurrentFrameScope() {
    143     masm_->set_has_frame(saved_);
    144   }
    145 
    146  private:
    147   MacroAssembler* masm_;
    148   bool saved_;
    149 };
    150 
    151 
    152 // Support for "structured" code comments.
    153 #ifdef DEBUG
    154 
    155 class Comment {
    156  public:
    157   Comment(MacroAssembler* masm, const char* msg);
    158   ~Comment();
    159 
    160  private:
    161   MacroAssembler* masm_;
    162   const char* msg_;
    163 };
    164 
    165 #else
    166 
    167 class Comment {
    168  public:
    169   Comment(MacroAssembler*, const char*)  {}
    170 };
    171 
    172 #endif  // DEBUG
    173 
    174 
    175 class AllocationUtils {
    176  public:
    177   static ExternalReference GetAllocationTopReference(
    178       Isolate* isolate, AllocationFlags flags) {
    179     if ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) {
    180       return ExternalReference::old_pointer_space_allocation_top_address(
    181           isolate);
    182     } else if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
    183       return ExternalReference::old_data_space_allocation_top_address(isolate);
    184     }
    185     return ExternalReference::new_space_allocation_top_address(isolate);
    186   }
    187 
    188 
    189   static ExternalReference GetAllocationLimitReference(
    190       Isolate* isolate, AllocationFlags flags) {
    191     if ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) {
    192       return ExternalReference::old_pointer_space_allocation_limit_address(
    193           isolate);
    194     } else if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
    195       return ExternalReference::old_data_space_allocation_limit_address(
    196           isolate);
    197     }
    198     return ExternalReference::new_space_allocation_limit_address(isolate);
    199   }
    200 };
    201 
    202 
    203 } }  // namespace v8::internal
    204 
    205 #endif  // V8_MACRO_ASSEMBLER_H_
    206