1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_ASM_ASSEMBLER_INLINE_HPP
  26 #define SHARE_VM_ASM_ASSEMBLER_INLINE_HPP
  27 
  28 #include "asm/assembler.hpp"
  29 #include "asm/codeBuffer.hpp"
  30 #include "compiler/disassembler.hpp"
  31 #include "runtime/threadLocalStorage.hpp"
  32 
  33 inline void AbstractAssembler::sync() {
  34   CodeSection* cs = code_section();
  35   guarantee(cs->start() == _code_begin, "must not shift code buffer");
  36   cs->set_end(_code_pos);
  37 }
  38 
  39 inline void AbstractAssembler::emit_byte(int x) {
  40   assert(isByte(x), "not a byte");
  41   *(unsigned char*)_code_pos = (unsigned char)x;
  42   _code_pos += sizeof(unsigned char);
  43   sync();
  44 }
  45 
  46 
  47 inline void AbstractAssembler::emit_word(int x) {
  48   *(short*)_code_pos = (short)x;
  49   _code_pos += sizeof(short);
  50   sync();
  51 }
  52 
  53 
  54 inline void AbstractAssembler::emit_long(jint x) {
  55   *(jint*)_code_pos = x;
  56   _code_pos += sizeof(jint);
  57   sync();
  58 }
  59 
  60 inline void AbstractAssembler::emit_address(address x) {
  61   *(address*)_code_pos = x;
  62   _code_pos += sizeof(address);
  63   sync();
  64 }
  65 
  66 inline address AbstractAssembler::inst_mark() const {
  67   return code_section()->mark();
  68 }
  69 
  70 
  71 inline void AbstractAssembler::set_inst_mark() {
  72   code_section()->set_mark();
  73 }
  74 
  75 
  76 inline void AbstractAssembler::clear_inst_mark() {
  77   code_section()->clear_mark();
  78 }
  79 
  80 
  81 inline void AbstractAssembler::relocate(RelocationHolder const& rspec, int format) {
  82   assert(!pd_check_instruction_mark()
  83          || inst_mark() == NULL || inst_mark() == _code_pos,
  84          "call relocate() between instructions");
  85   code_section()->relocate(_code_pos, rspec, format);
  86 }
  87 
  88 
  89 inline CodeBuffer* AbstractAssembler::code() const {
  90   return code_section()->outer();
  91 }
  92 
  93 inline int AbstractAssembler::sect() const {
  94   return code_section()->index();
  95 }
  96 
  97 inline int AbstractAssembler::locator() const {
  98   return CodeBuffer::locator(offset(), sect());
  99 }
 100 
 101 inline address AbstractAssembler::target(Label& L) {
 102   return code_section()->target(L, pc());
 103 }
 104 
 105 inline int Label::loc_pos() const {
 106   return CodeBuffer::locator_pos(loc());
 107 }
 108 
 109 inline int Label::loc_sect() const {
 110   return CodeBuffer::locator_sect(loc());
 111 }
 112 
 113 inline void Label::bind_loc(int pos, int sect) {
 114   bind_loc(CodeBuffer::locator(pos, sect));
 115 }
 116 
 117 address AbstractAssembler::address_constant(Label& L) {
 118   address c = NULL;
 119   address ptr = start_a_const(sizeof(c), sizeof(c));
 120   if (ptr != NULL) {
 121     relocate(Relocation::spec_simple(relocInfo::internal_word_type));
 122     *(address*)ptr = c = code_section()->target(L, ptr);
 123     _code_pos = ptr + sizeof(c);
 124     end_a_const();
 125   }
 126   return ptr;
 127 }
 128 
 129 address AbstractAssembler::address_table_constant(GrowableArray<Label*> labels) {
 130   int addressSize = sizeof(address);
 131   int sizeLabel = addressSize * labels.length();
 132   address ptr = start_a_const(sizeLabel, addressSize);
 133 
 134   if (ptr != NULL) {
 135     address *labelLoc = (address*)ptr;
 136     for (int i=0; i < labels.length(); i++) {
 137       emit_address(code_section()->target(*labels.at(i), (address)&labelLoc[i]));
 138       code_section()->relocate((address)&labelLoc[i], relocInfo::internal_word_type);
 139     }
 140     end_a_const();
 141   }
 142   return ptr;
 143 }
 144 
 145 #endif // SHARE_VM_ASM_ASSEMBLER_INLINE_HPP