23 */ |
23 */ |
24 |
24 |
25 #ifndef SHARE_VM_CODE_STUBS_HPP |
25 #ifndef SHARE_VM_CODE_STUBS_HPP |
26 #define SHARE_VM_CODE_STUBS_HPP |
26 #define SHARE_VM_CODE_STUBS_HPP |
27 |
27 |
|
28 #include "asm/codeBuffer.hpp" |
28 #include "memory/allocation.hpp" |
29 #include "memory/allocation.hpp" |
29 #ifdef TARGET_OS_FAMILY_linux |
30 #ifdef TARGET_OS_FAMILY_linux |
30 # include "os_linux.inline.hpp" |
31 # include "os_linux.inline.hpp" |
31 #endif |
32 #endif |
32 #ifdef TARGET_OS_FAMILY_solaris |
33 #ifdef TARGET_OS_FAMILY_solaris |
69 |
70 |
70 |
71 |
71 class Stub VALUE_OBJ_CLASS_SPEC { |
72 class Stub VALUE_OBJ_CLASS_SPEC { |
72 public: |
73 public: |
73 // Initialization/finalization |
74 // Initialization/finalization |
74 void initialize(int size) { ShouldNotCallThis(); } // called to initialize/specify the stub's size |
75 void initialize(int size, |
|
76 CodeComments& comments) { ShouldNotCallThis(); } // called to initialize/specify the stub's size |
75 void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated |
77 void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated |
76 |
78 |
77 // General info/converters |
79 // General info/converters |
78 int size() const { ShouldNotCallThis(); return 0; } // must return the size provided by initialize |
80 int size() const { ShouldNotCallThis(); return 0; } // must return the size provided by initialize |
79 static int code_size_to_size(int code_size) { ShouldNotCallThis(); return 0; } // computes the size given the code size |
81 static int code_size_to_size(int code_size) { ShouldNotCallThis(); return 0; } // computes the size given the code size |
102 // one stub interface instance required per stub queue. |
104 // one stub interface instance required per stub queue. |
103 |
105 |
104 class StubInterface: public CHeapObj<mtCode> { |
106 class StubInterface: public CHeapObj<mtCode> { |
105 public: |
107 public: |
106 // Initialization/finalization |
108 // Initialization/finalization |
107 virtual void initialize(Stub* self, int size) = 0; // called after creation (called twice if allocated via (request, commit)) |
109 virtual void initialize(Stub* self, int size, |
|
110 CodeComments& comments) = 0; // called after creation (called twice if allocated via (request, commit)) |
108 virtual void finalize(Stub* self) = 0; // called before deallocation |
111 virtual void finalize(Stub* self) = 0; // called before deallocation |
109 |
112 |
110 // General info/converters |
113 // General info/converters |
111 virtual int size(Stub* self) const = 0; // the total size of the stub in bytes (must be a multiple of CodeEntryAlignment) |
114 virtual int size(Stub* self) const = 0; // the total size of the stub in bytes (must be a multiple of CodeEntryAlignment) |
112 virtual int code_size_to_size(int code_size) const = 0; // computes the total stub size in bytes given the code size in bytes |
115 virtual int code_size_to_size(int code_size) const = 0; // computes the total stub size in bytes given the code size in bytes |
130 private: \ |
133 private: \ |
131 static stub* cast(Stub* self) { return (stub*)self; } \ |
134 static stub* cast(Stub* self) { return (stub*)self; } \ |
132 \ |
135 \ |
133 public: \ |
136 public: \ |
134 /* Initialization/finalization */ \ |
137 /* Initialization/finalization */ \ |
135 virtual void initialize(Stub* self, int size) { cast(self)->initialize(size); } \ |
138 virtual void initialize(Stub* self, int size, \ |
|
139 CodeComments& comments) { cast(self)->initialize(size, comments); } \ |
136 virtual void finalize(Stub* self) { cast(self)->finalize(); } \ |
140 virtual void finalize(Stub* self) { cast(self)->finalize(); } \ |
137 \ |
141 \ |
138 /* General info */ \ |
142 /* General info */ \ |
139 virtual int size(Stub* self) const { return cast(self)->size(); } \ |
143 virtual int size(Stub* self) const { return cast(self)->size(); } \ |
140 virtual int code_size_to_size(int code_size) const { return stub::code_size_to_size(code_size); } \ |
144 virtual int code_size_to_size(int code_size) const { return stub::code_size_to_size(code_size); } \ |
169 int index_of(Stub* s) const { int i = (address)s - _stub_buffer; check_index(i); return i; } |
173 int index_of(Stub* s) const { int i = (address)s - _stub_buffer; check_index(i); return i; } |
170 Stub* stub_at(int i) const { check_index(i); return (Stub*)(_stub_buffer + i); } |
174 Stub* stub_at(int i) const { check_index(i); return (Stub*)(_stub_buffer + i); } |
171 Stub* current_stub() const { return stub_at(_queue_end); } |
175 Stub* current_stub() const { return stub_at(_queue_end); } |
172 |
176 |
173 // Stub functionality accessed via interface |
177 // Stub functionality accessed via interface |
174 void stub_initialize(Stub* s, int size) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size); } |
178 void stub_initialize(Stub* s, int size, |
|
179 CodeComments& comments) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); } |
175 void stub_finalize(Stub* s) { _stub_interface->finalize(s); } |
180 void stub_finalize(Stub* s) { _stub_interface->finalize(s); } |
176 int stub_size(Stub* s) const { return _stub_interface->size(s); } |
181 int stub_size(Stub* s) const { return _stub_interface->size(s); } |
177 bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } |
182 bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } |
178 int stub_code_size_to_size(int code_size) const { return _stub_interface->code_size_to_size(code_size); } |
183 int stub_code_size_to_size(int code_size) const { return _stub_interface->code_size_to_size(code_size); } |
179 void stub_verify(Stub* s) { _stub_interface->verify(s); } |
184 void stub_verify(Stub* s) { _stub_interface->verify(s); } |
198 address code_end() const { return _stub_buffer + _buffer_limit; } |
203 address code_end() const { return _stub_buffer + _buffer_limit; } |
199 |
204 |
200 // Stub allocation (atomic transactions) |
205 // Stub allocation (atomic transactions) |
201 Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code |
206 Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code |
202 Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue |
207 Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue |
203 void commit (int committed_code_size); // commit the previously requested stub - unlocks the queue |
208 void commit (int committed_code_size, |
|
209 CodeComments& comments); // commit the previously requested stub - unlocks the queue |
204 |
210 |
205 // Stub deallocation |
211 // Stub deallocation |
206 void remove_first(); // remove the first stub in the queue |
212 void remove_first(); // remove the first stub in the queue |
207 void remove_first(int n); // remove the first n stubs in the queue |
213 void remove_first(int n); // remove the first n stubs in the queue |
208 void remove_all(); // remove all stubs in the queue |
214 void remove_all(); // remove all stubs in the queue |