00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef DELTA_COMPILER
00026
00027
00028
00029
00030
00031 class Array;
00032 class ByteArray;
00033 class NonInlinedBlockScopeNode;
00034
00035
00036 class ScopeDescRecorder: public ResourceObj {
00037 private:
00038 bool _hasCodeBeenGenerated;
00039 Array* oops;
00040 Array* values;
00041 ByteArray* codes;
00042 PcDescInfo pcs;
00043
00044 GrowableArray<klassOop>* dependants;
00045 int dependants_end;
00046
00047 NonInlinedBlockScopeNode* nonInlinedBlockScopesHead;
00048 NonInlinedBlockScopeNode* nonInlinedBlockScopesTail;
00049
00050 public:
00051 ScopeInfo root;
00052
00053
00054 int offset(ScopeInfo scope);
00055 int offset_for_noninlined_scope_node(NonInlinedBlockScopeNode* scope);
00056
00057 ScopeDescRecorder(int scopeSize,
00058 int npcDesc);
00059
00060
00061 ScopeInfo addMethodScope(LookupKey* key,
00062 methodOop method,
00063 LogicalAddress* receiver_location,
00064 bool allocates_compiled_context,
00065 bool lite = false,
00066 int scopeID = 0,
00067 ScopeInfo senderScope = NULL,
00068 int senderBCI = IllegalBCI,
00069 bool visible = false);
00070
00071
00072
00073 ScopeInfo addBlockScope(methodOop method,
00074 ScopeInfo parent,
00075 bool allocates_compiled_context,
00076 bool lite = false,
00077 int scopeID = 0,
00078 ScopeInfo senderScope = NULL,
00079 int senderBCI = IllegalBCI,
00080 bool visible = false);
00081
00082
00083 ScopeInfo addTopLevelBlockScope(methodOop method,
00084 LogicalAddress* receiver_location,
00085 klassOop receiver_klass,
00086 bool allocates_compiled_context);
00087
00088
00089
00090 NonInlinedBlockScopeNode* addNonInlinedBlockScope(methodOop block_method, ScopeInfo parent);
00091
00092
00093 void addTemporary (ScopeInfo scope, int index, LogicalAddress* location);
00094 void addContextTemporary (ScopeInfo scope, int index, LogicalAddress* location);
00095 void addExprStack (ScopeInfo scope, int bci, LogicalAddress* location);
00096
00097 LogicalAddress* createLogicalAddress(NameNode* initial_value);
00098 void changeLogicalAddress(LogicalAddress* location, NameNode* new_value, int pc_offset);
00099
00100
00101
00102
00103
00104
00105
00106
00107 void addArgument(ScopeInfo scope, int index, LogicalAddress* location);
00108
00109
00110 void addPcDesc(int pcOffset, ScopeInfo scope, int bci);
00111 void addIllegalPcDesc(int pcOffset);
00112
00113
00114 void add_dependant(LookupKey* key);
00115
00116
00117 int size();
00118
00119
00120 void copyTo(nmethod* nm);
00121
00122 void verify(nmethodScopes* scopes);
00123
00124
00125 void generate();
00126
00127 private:
00128
00129 Location convert_location(Location loc);
00130
00131 ScopeInfo addScope(ScopeInfo scope, ScopeInfo senderScope);
00132 NonInlinedBlockScopeNode* addNonInlinedBlockScope(NonInlinedBlockScopeNode* scope);
00133
00134 void genScopeDescHeader(u_char code,
00135 bool lite,
00136 bool args,
00137 bool temps,
00138 bool context_temps,
00139 bool expr_stack,
00140 bool has_context,
00141 bool bigHeader);
00142
00143
00144 void generateDependencies();
00145
00146 void emit_termination_node();
00147 void emit_illegal_node(bool is_last);
00148
00149
00150
00151 int updateScopeDescHeader(int offset, int next);
00152
00153 void updateExtScopeDescHeader(int offset, int next);
00154
00155 inline int getValueIndex(int v);
00156 inline int getOopIndex(oop o);
00157
00158 inline void genIndex(int index);
00159 void genValue(int v);
00160 void genOop(oop o);
00161
00162
00163 friend class NameNode;
00164 friend class LocationName;
00165 friend class ValueName;
00166 friend class MemoizedName;
00167 friend class BlockValueName;
00168 friend class IllegalName;
00169
00170 friend class ScopeDescNode;
00171 friend class MethodScopeNode;
00172 friend class BlockScopeNode;
00173 friend class TopLevelBlockScopeNode;
00174 friend class NonInlinedBlockScopeNode;
00175
00176 friend class LogicalAddress;
00177 friend class NameList;
00178 };
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 class NameNode: public ResourceObj {
00189 public:
00190 bool genHeaderByte(ScopeDescRecorder* rec, u_char code, bool is_last, int index);
00191
00192 virtual bool hasLocation() { return false; }
00193 virtual bool isIllegal() { return false; }
00194 virtual Location location() { ShouldNotCallThis(); return unAllocated; }
00195 virtual void generate(ScopeDescRecorder* rec, bool is_last) = 0;
00196 };
00197
00198
00199
00200 class LocationName: public NameNode {
00201 private:
00202 Location l;
00203
00204 void generate(ScopeDescRecorder* rec, bool is_last);
00205
00206 public:
00207 LocationName(Location ln) { l = ln; }
00208 bool hasLocation() { return true; }
00209 Location location() { return l; }
00210 };
00211
00212
00213
00214 class ValueName: public NameNode {
00215 private:
00216 oop value;
00217
00218 void generate(ScopeDescRecorder* rec, bool is_last);
00219
00220 public:
00221 ValueName(oop val) {
00222 value = val;
00223 assert(!val->is_block(), "should use BlockValueName");
00224 }
00225 };
00226
00227
00228
00229 class BlockValueName: public NameNode {
00230 private:
00231 methodOop block_method;
00232 ScopeInfo parent_scope;
00233
00234 void generate(ScopeDescRecorder* rec, bool is_last);
00235
00236 public:
00237 BlockValueName(methodOop block_method, ScopeInfo parent_scope) {
00238 this->block_method = block_method;
00239 this->parent_scope = parent_scope;
00240 }
00241 };
00242
00243
00244
00245
00246
00247
00248 class MemoizedName: public NameNode {
00249 private:
00250 Location loc;
00251 methodOop block_method;
00252 ScopeInfo parent_scope;
00253
00254 void generate(ScopeDescRecorder* rec, bool is_last);
00255
00256 public:
00257 MemoizedName(Location loc, methodOop block_method, ScopeInfo parent_scope) {
00258 this->loc = loc;
00259 this->block_method = block_method;
00260 this->parent_scope = parent_scope;
00261 }
00262 bool hasLocation() { return true; }
00263 Location location() { return loc; }
00264 };
00265
00266
00267 NameNode* newValueName(oop value);
00268
00269
00270
00271
00272 class IllegalName: public NameNode {
00273 private:
00274 bool isIllegal() { return true; }
00275 void generate(ScopeDescRecorder* rec, bool is_last);
00276 };
00277
00278 enum {
00279 LOCATION_CODE,
00280 VALUE_CODE,
00281 BLOCKVALUE_CODE,
00282 MEMOIZEDBLOCK_CODE
00283 };
00284
00285
00286 class nameDescHeaderByte : public ValueObj {
00287 private:
00288 u_char byte;
00289 static const u_char code_width;
00290 static const u_char index_width;
00291 static const u_char is_last_bit_num;
00292 static const u_char max_code;
00293
00294 u_char raw_index() { return lowerBits(byte >> code_width, index_width); }
00295
00296 public:
00297 static const u_char max_index;
00298 static const u_char no_index;
00299 static const u_char termination_index;
00300 static const u_char illegal_index;
00301
00302 u_char value() { return byte; }
00303
00304 u_char code() {
00305 return lowerBits(byte, code_width);
00306 }
00307
00308 u_char index() {
00309 assert(has_index(), "must have valid index");
00310 return raw_index();
00311 }
00312
00313 bool is_illegal() { return raw_index() == illegal_index; }
00314 bool is_termination() { return raw_index() == termination_index; }
00315 bool is_last() { return isSet(byte, is_last_bit_num); }
00316 bool has_index() { return raw_index() <= max_index; }
00317
00318 void pack(u_char code, bool is_last, u_char i) {
00319 assert( code <= max_code, "code to high");
00320 assert( i <= no_index, "index to high");
00321 byte = addBits(i << code_width, code);
00322 if (is_last) byte = setNth(byte, is_last_bit_num);
00323 }
00324
00325 void pack_illegal(bool is_last) {
00326 byte = addBits(illegal_index << code_width, 0);
00327 if (is_last) byte = setNth(byte, is_last_bit_num);
00328 }
00329
00330 void pack_termination(bool is_last) {
00331 byte = addBits(termination_index << code_width, 0);
00332 if (is_last) byte = setNth(byte, is_last_bit_num);
00333 }
00334
00335 void unpack(u_char value) { byte = value; }
00336 };
00337
00338 class scopeDescHeaderByte : public ValueObj {
00339 private:
00340 u_char byte;
00341 static const u_char code_width;
00342 static const u_char max_code;
00343 static const u_char lite_bit_num;
00344 static const u_char args_bit_num;
00345 static const u_char temps_bit_num;
00346 static const u_char context_temps_bit_num;
00347 static const u_char expr_stack_bit_num;
00348 static const u_char context_bit_num;
00349 public:
00350 u_char value() { return byte; }
00351 u_char code() { return lowerBits(byte, code_width); }
00352 bool is_lite() { return isSet(byte, lite_bit_num); }
00353 bool has_args() { return isSet(byte, args_bit_num); }
00354 bool has_temps() { return isSet(byte, temps_bit_num); }
00355 bool has_context_temps() { return isSet(byte, context_temps_bit_num); }
00356 bool has_expr_stack() { return isSet(byte, expr_stack_bit_num); }
00357 bool has_compiled_context() { return isSet(byte, context_bit_num); }
00358
00359 bool has_nameDescs() { return has_args()
00360 || has_temps()
00361 || has_context_temps()
00362 || has_expr_stack(); }
00363
00364 void pack(u_char code, bool lite, bool args, bool temps, bool context_temps, bool expr_stack, bool has_compiled_context) {
00365 assert( code <= max_code, "code to high");
00366 byte = code;
00367 if (lite) byte = setNth(byte, lite_bit_num);
00368 if (args) byte = setNth(byte, args_bit_num);
00369 if (temps) byte = setNth(byte, temps_bit_num);
00370 if (context_temps) byte = setNth(byte, context_temps_bit_num);
00371 if (expr_stack) byte = setNth(byte, expr_stack_bit_num);
00372 if (has_compiled_context) byte = setNth(byte, context_bit_num);
00373 }
00374
00375 void unpack(u_char value) { byte = value; }
00376 };
00377
00378 # define BYTE_WIDTH 8
00379 # define EXTENDED_INDEX nthMask(BYTE_WIDTH)
00380 # define MAX_INLINE_VALUE nthMask(BYTE_WIDTH-1)
00381
00382 enum {
00383 METHOD_CODE,
00384 BLOCK_CODE,
00385 TOPLEVELBLOCK_CODE,
00386 NONINLINED_BLOCK_CODE
00387 };
00388
00389 #endif