LCOV - code coverage report
Current view: top level - src - macro-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 24 24 100.0 %
Date: 2017-04-26 Functions: 4 4 100.0 %

          Line data    Source code
       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             : #include "src/assembler-inl.h"
       9             : 
      10             : // Helper types to make boolean flag easier to read at call-site.
      11             : enum InvokeFlag {
      12             :   CALL_FUNCTION,
      13             :   JUMP_FUNCTION
      14             : };
      15             : 
      16             : 
      17             : // Flags used for the AllocateInNewSpace functions.
      18             : enum AllocationFlags {
      19             :   // No special flags.
      20             :   NO_ALLOCATION_FLAGS = 0,
      21             :   // The content of the result register already contains the allocation top in
      22             :   // new space.
      23             :   RESULT_CONTAINS_TOP = 1 << 0,
      24             :   // Specify that the requested size of the space to allocate is specified in
      25             :   // words instead of bytes.
      26             :   SIZE_IN_WORDS = 1 << 1,
      27             :   // Align the allocation to a multiple of kDoubleSize
      28             :   DOUBLE_ALIGNMENT = 1 << 2,
      29             :   // Directly allocate in old space
      30             :   PRETENURE = 1 << 3,
      31             :   // Allocation folding dominator
      32             :   ALLOCATION_FOLDING_DOMINATOR = 1 << 4,
      33             :   // Folded allocation
      34             :   ALLOCATION_FOLDED = 1 << 5
      35             : };
      36             : 
      37             : #if V8_TARGET_ARCH_IA32
      38             : #include "src/ia32/macro-assembler-ia32.h"
      39             : #elif V8_TARGET_ARCH_X64
      40             : #include "src/x64/macro-assembler-x64.h"
      41             : #elif V8_TARGET_ARCH_ARM64
      42             : #include "src/arm64/constants-arm64.h"
      43             : #include "src/arm64/macro-assembler-arm64.h"
      44             : #elif V8_TARGET_ARCH_ARM
      45             : #include "src/arm/constants-arm.h"
      46             : #include "src/arm/macro-assembler-arm.h"
      47             : #elif V8_TARGET_ARCH_PPC
      48             : #include "src/ppc/constants-ppc.h"
      49             : #include "src/ppc/macro-assembler-ppc.h"
      50             : #elif V8_TARGET_ARCH_MIPS
      51             : #include "src/mips/constants-mips.h"
      52             : #include "src/mips/macro-assembler-mips.h"
      53             : #elif V8_TARGET_ARCH_MIPS64
      54             : #include "src/mips64/constants-mips64.h"
      55             : #include "src/mips64/macro-assembler-mips64.h"
      56             : #elif V8_TARGET_ARCH_S390
      57             : #include "src/s390/constants-s390.h"
      58             : #include "src/s390/macro-assembler-s390.h"
      59             : #elif V8_TARGET_ARCH_X87
      60             : #include "src/x87/macro-assembler-x87.h"
      61             : #else
      62             : #error Unsupported target architecture.
      63             : #endif
      64             : 
      65             : namespace v8 {
      66             : namespace internal {
      67             : 
      68             : // Simulators only support C calls with up to kMaxCParameters parameters.
      69             : static constexpr int kMaxCParameters = 9;
      70             : 
      71             : class FrameScope {
      72             :  public:
      73     5512240 :   explicit FrameScope(MacroAssembler* masm, StackFrame::Type type)
      74     5512240 :       : masm_(masm), type_(type), old_has_frame_(masm->has_frame()) {
      75             :     masm->set_has_frame(true);
      76     2756120 :     if (type != StackFrame::MANUAL && type_ != StackFrame::NONE) {
      77      119962 :       masm->EnterFrame(type);
      78             :     }
      79     2756120 :   }
      80             : 
      81     2756120 :   ~FrameScope() {
      82     2756120 :     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
      83      119962 :       masm_->LeaveFrame(type_);
      84             :     }
      85     2756120 :     masm_->set_has_frame(old_has_frame_);
      86     2756120 :   }
      87             : 
      88             :   // Normally we generate the leave-frame code when this object goes
      89             :   // out of scope.  Sometimes we may need to generate the code somewhere else
      90             :   // in addition.  Calling this will achieve that, but the object stays in
      91             :   // scope, the MacroAssembler is still marked as being in a frame scope, and
      92             :   // the code will be generated again when it goes out of scope.
      93             :   void GenerateLeaveFrame() {
      94             :     DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
      95          43 :     masm_->LeaveFrame(type_);
      96             :   }
      97             : 
      98             :  private:
      99             :   MacroAssembler* masm_;
     100             :   StackFrame::Type type_;
     101             :   bool old_has_frame_;
     102             : };
     103             : 
     104             : class FrameAndConstantPoolScope {
     105             :  public:
     106             :   FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
     107             :       : masm_(masm),
     108             :         type_(type),
     109             :         old_has_frame_(masm->has_frame()),
     110             :         old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
     111             :                                      masm->is_constant_pool_available()) {
     112             :     masm->set_has_frame(true);
     113             :     if (FLAG_enable_embedded_constant_pool) {
     114             :       masm->set_constant_pool_available(true);
     115             :     }
     116             :     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
     117             :       masm->EnterFrame(type, !old_constant_pool_available_);
     118             :     }
     119             :   }
     120             : 
     121             :   ~FrameAndConstantPoolScope() {
     122             :     masm_->LeaveFrame(type_);
     123             :     masm_->set_has_frame(old_has_frame_);
     124             :     if (FLAG_enable_embedded_constant_pool) {
     125             :       masm_->set_constant_pool_available(old_constant_pool_available_);
     126             :     }
     127             :   }
     128             : 
     129             :   // Normally we generate the leave-frame code when this object goes
     130             :   // out of scope.  Sometimes we may need to generate the code somewhere else
     131             :   // in addition.  Calling this will achieve that, but the object stays in
     132             :   // scope, the MacroAssembler is still marked as being in a frame scope, and
     133             :   // the code will be generated again when it goes out of scope.
     134             :   void GenerateLeaveFrame() {
     135             :     DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
     136             :     masm_->LeaveFrame(type_);
     137             :   }
     138             : 
     139             :  private:
     140             :   MacroAssembler* masm_;
     141             :   StackFrame::Type type_;
     142             :   bool old_has_frame_;
     143             :   bool old_constant_pool_available_;
     144             : 
     145             :   DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
     146             : };
     147             : 
     148             : // Class for scoping the the unavailability of constant pool access.
     149             : class ConstantPoolUnavailableScope {
     150             :  public:
     151             :   explicit ConstantPoolUnavailableScope(Assembler* assembler)
     152             :       : assembler_(assembler),
     153             :         old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
     154             :                                      assembler->is_constant_pool_available()) {
     155             :     if (FLAG_enable_embedded_constant_pool) {
     156             :       assembler->set_constant_pool_available(false);
     157             :     }
     158             :   }
     159             :   ~ConstantPoolUnavailableScope() {
     160             :     if (FLAG_enable_embedded_constant_pool) {
     161             :       assembler_->set_constant_pool_available(old_constant_pool_available_);
     162             :     }
     163             :   }
     164             : 
     165             :  private:
     166             :   Assembler* assembler_;
     167             :   int old_constant_pool_available_;
     168             : 
     169             :   DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
     170             : };
     171             : 
     172             : 
     173      254606 : class AllowExternalCallThatCantCauseGC: public FrameScope {
     174             :  public:
     175             :   explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
     176      254606 :       : FrameScope(masm, StackFrame::NONE) { }
     177             : };
     178             : 
     179             : 
     180             : class NoCurrentFrameScope {
     181             :  public:
     182      137654 :   explicit NoCurrentFrameScope(MacroAssembler* masm)
     183             :       : masm_(masm), saved_(masm->has_frame()) {
     184             :     masm->set_has_frame(false);
     185             :   }
     186             : 
     187             :   ~NoCurrentFrameScope() {
     188             :     masm_->set_has_frame(saved_);
     189             :   }
     190             : 
     191             :  private:
     192             :   MacroAssembler* masm_;
     193             :   bool saved_;
     194             : };
     195             : 
     196             : 
     197             : // Support for "structured" code comments.
     198             : #ifdef DEBUG
     199             : 
     200             : class Comment {
     201             :  public:
     202             :   Comment(Assembler* assembler, const char* msg);
     203             :   ~Comment();
     204             : 
     205             :  private:
     206             :   Assembler* assembler_;
     207             :   const char* msg_;
     208             : };
     209             : 
     210             : #else
     211             : 
     212             : class Comment {
     213             :  public:
     214             :   Comment(Assembler*, const char*) {}
     215             : };
     216             : 
     217             : #endif  // DEBUG
     218             : 
     219             : 
     220             : // Wrapper class for passing expected and actual parameter counts as
     221             : // either registers or immediate values. Used to make sure that the
     222             : // caller provides exactly the expected number of parameters to the
     223             : // callee.
     224             : class ParameterCount BASE_EMBEDDED {
     225             :  public:
     226        6845 :   explicit ParameterCount(Register reg) : reg_(reg), immediate_(0) {}
     227       17807 :   explicit ParameterCount(int imm) : reg_(no_reg), immediate_(imm) {}
     228             : 
     229             :   bool is_reg() const { return !reg_.is(no_reg); }
     230             :   bool is_immediate() const { return !is_reg(); }
     231             : 
     232             :   Register reg() const {
     233             :     DCHECK(is_reg());
     234             :     return reg_;
     235             :   }
     236             :   int immediate() const {
     237             :     DCHECK(is_immediate());
     238             :     return immediate_;
     239             :   }
     240             : 
     241             :  private:
     242             :   const Register reg_;
     243             :   const int immediate_;
     244             : 
     245             :   DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterCount);
     246             : };
     247             : 
     248             : 
     249             : class AllocationUtils {
     250             :  public:
     251      105548 :   static ExternalReference GetAllocationTopReference(
     252             :       Isolate* isolate, AllocationFlags flags) {
     253      105548 :     if ((flags & PRETENURE) != 0) {
     254         104 :       return ExternalReference::old_space_allocation_top_address(isolate);
     255             :     }
     256      105444 :     return ExternalReference::new_space_allocation_top_address(isolate);
     257             :   }
     258             : 
     259             : 
     260       47953 :   static ExternalReference GetAllocationLimitReference(
     261             :       Isolate* isolate, AllocationFlags flags) {
     262       47953 :     if ((flags & PRETENURE) != 0) {
     263           8 :       return ExternalReference::old_space_allocation_limit_address(isolate);
     264             :     }
     265       47945 :     return ExternalReference::new_space_allocation_limit_address(isolate);
     266             :   }
     267             : };
     268             : 
     269             : 
     270             : }  // namespace internal
     271             : }  // namespace v8
     272             : 
     273             : #endif  // V8_MACRO_ASSEMBLER_H_

Generated by: LCOV version 1.10