duke@435: /* stefank@2314: * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef SHARE_VM_CODE_LOCATION_HPP stefank@2314: #define SHARE_VM_CODE_LOCATION_HPP stefank@2314: stefank@2314: #include "asm/assembler.hpp" stefank@2314: #include "code/vmreg.hpp" stefank@2314: #include "memory/allocation.hpp" stefank@2314: duke@435: // A Location describes a concrete machine variable location duke@435: // (such as integer or floating point register or a stack-held duke@435: // variable). Used when generating debug-information for nmethods. duke@435: // duke@435: // Encoding: duke@435: // kvn@766: // bits (use low bits for best compression): kvn@766: // Type: [3..0] kvn@766: // Where: [4] kvn@766: // Offset: [31..5] duke@435: duke@435: class Location VALUE_OBJ_CLASS_SPEC { duke@435: friend class VMStructs; duke@435: public: duke@435: enum Where { duke@435: on_stack, duke@435: in_register duke@435: }; duke@435: duke@435: enum Type { kvn@766: invalid, // Invalid location duke@435: normal, // Ints, floats, double halves duke@435: oop, // Oop (please GC me!) duke@435: int_in_long, // Integer held in long register duke@435: lng, // Long held in one register duke@435: float_in_dbl, // Float held in double register duke@435: dbl, // Double held in one register duke@435: addr, // JSR return address kvn@766: narrowoop // Narrow Oop (please GC me!) duke@435: }; duke@435: duke@435: duke@435: private: duke@435: enum { kvn@766: TYPE_MASK = (juint) 0x0F, kvn@766: TYPE_SHIFT = 0, kvn@766: WHERE_MASK = (juint) 0x10, kvn@766: WHERE_SHIFT = 4, kvn@766: OFFSET_MASK = (juint) 0xFFFFFFE0, kvn@766: OFFSET_SHIFT = 5 duke@435: }; duke@435: kvn@766: juint _value; duke@435: duke@435: // Create a bit-packed Location duke@435: Location(Where where_, Type type_, unsigned offset_) { duke@435: set(where_, type_, offset_); duke@435: assert( where () == where_ , "" ); duke@435: assert( type () == type_ , "" ); duke@435: assert( offset() == offset_, "" ); duke@435: } duke@435: duke@435: inline void set(Where where_, Type type_, unsigned offset_) { kvn@766: _value = (juint) ((where_ << WHERE_SHIFT) | kvn@766: (type_ << TYPE_SHIFT) | kvn@766: ((offset_ << OFFSET_SHIFT) & OFFSET_MASK)); duke@435: } duke@435: duke@435: public: duke@435: duke@435: // Stack location Factory. Offset is 4-byte aligned; remove low bits duke@435: static Location new_stk_loc( Type t, int offset ) { return Location(on_stack,t,offset>>LogBytesPerInt); } duke@435: // Register location Factory duke@435: static Location new_reg_loc( Type t, VMReg reg ) { return Location(in_register, t, reg->value()); } duke@435: // Default constructor kvn@766: Location() { set(on_stack,invalid,0); } duke@435: duke@435: // Bit field accessors duke@435: Where where() const { return (Where) ((_value & WHERE_MASK) >> WHERE_SHIFT);} duke@435: Type type() const { return (Type) ((_value & TYPE_MASK) >> TYPE_SHIFT); } duke@435: unsigned offset() const { return (unsigned) ((_value & OFFSET_MASK) >> OFFSET_SHIFT); } duke@435: duke@435: // Accessors duke@435: bool is_register() const { return where() == in_register; } duke@435: bool is_stack() const { return where() == on_stack; } duke@435: duke@435: int stack_offset() const { assert(where() == on_stack, "wrong Where"); return offset()<