1 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.17 $ */
2 /* Copyright (c) 2006, Sun Microsystems, Inc.
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6 following conditions are met:
8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
10 disclaimer in the documentation and/or other materials provided with the distribution.
11 * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived
12 from this software without specific prior written permission.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
15 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
16 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
19 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
24 // The jumpTable constitutes the interface between interpreter code and optimized code.
25 // This indirection makes it possible to invalidate optimized code without
26 // - keeping track of dependencies between sends in methodsOops and optimized code, or
27 // - traverse all methodOops.
28 // If optimized code has become invalid the jump table entry is simply snapped.
29 // In addition the jumpTable serves as a dispatch table for block closures for optimized code.
31 // %implementation note:
32 // make jumpTable growable
39 class jumpTableID
: ValueObj
{
42 friend class jumpTable
;
44 enum { max_value
= nthMask(16) };
47 jumpTableID() : _major(max_value
), _minor(max_value
) {}
48 jumpTableID(u_short major
) : _major(major
), _minor(max_value
) {}
49 jumpTableID(u_short major
, u_short minor
) : _major(major
), _minor(minor
) {}
50 bool has_minor() const { return _minor
!= max_value
; }
51 bool is_block() const { return _minor
> 0; }
52 bool is_valid() const { return _major
!= max_value
; }
53 u_short
major() const { return _major
; }
54 u_short
minor() const { return _minor
; }
55 jumpTableID
sub(u_short minor
) const { return jumpTableID(_major
, minor
); }
59 class jumpTable
: public ValueObj
{
61 int firstFree
; // index of first free elem
62 static char* allocate_jump_entries(int size
);
63 static jumpTableEntry
* jump_entry_for_at(char* entries
, int index
);
64 jumpTableEntry
* major_at(u_short index
);
67 int length
; // max. number of IDs
68 int usedIDs
; // # of used ID
76 // Allocates a block of adjacent jump table entries.
77 jumpTableID
allocate(int number_of_entries
);
79 // returns the jumptable entry for id
80 jumpTableEntry
* at(jumpTableID id
);
82 int newID(); // return a new ID
83 int peekID(); // return value which would be returned by newID,
84 // but don't actually allocate the ID
85 void freeID(int index
); // index is unused again
90 // compilation of blocks
91 static char* compile_new_block(blockClosureOop blk
); // create nmethod, return entry point
92 static nmethod
* compile_block(blockClosureOop blk
); // (re)compile block nmethod
94 friend class jumpTableEntry
;
98 // implementation note: jumpTableEntry should be an abstract class with two
99 // subclasses for nmethod and block entries, but these classes are combined
100 // in order to save space (no vtbl pointer needed)
101 class jumpTableEntry
: public ValueObj
{
103 char* jump_inst_addr() const { assert(oop(this)->is_smi(), "misaligned"); return (char*) this; }
104 char* state_addr() const { return ((char*) this) + sizeof(char) + sizeof(int); }
105 char state() const { return *state_addr(); }
106 void fill_entry(char instr
, char* dest
, char state
);
107 void initialize_as_unused(int index
);
108 void initialize_as_link(char* link
);
109 void initialize_nmethod_stub(char* dest
);
110 void initialize_block_closure_stub();
111 inline jumpTableEntry
* previous_stub() const;
112 inline jumpTableEntry
* next_stub() const;
113 jumpTableEntry
* parent_entry(int& index
) const;
114 void report_verify_error(char* message
);
116 // testing operations LARS: please add comments explaining what the 4 cases are -Urs 4/96
117 bool is_nmethod_stub() const;
118 bool is_block_closure_stub() const;
119 bool is_link() const;
120 bool is_unused() const;
123 char* entry_point() const { return jump_inst_addr(); }
126 char** destination_addr() const; // the address of the destination
127 char* destination() const; // current destination
128 void set_destination(char* dest
); // sets the destination
130 // operations for link stubs
133 // operations for unused
134 int next_free() const;
136 // operations for nmethod stubs (is_nmethod_stub() == true)
137 nmethod
* method() const; // NULL if not pointing to a method
139 // operations for block stubs (is_block_closure_stub() == true)
140 bool block_has_nmethod() const;
141 nmethod
* block_nmethod() const; // block nmethod (or NULL if not compiled yet)
142 methodOop
block_method() const; // block method
143 // nmethod creating the blockClosureOops pointing to this entry
144 // index is set to the distance |parent_entry - this|
145 nmethod
* parent_nmethod(int& index
) const;
151 // size of jump table entry
152 static int size() { return 8; }
154 friend class jumpTable
;