00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025
00026 #ifdef DELTA_COMPILER
00027
00028 # include "incls/_scopeDescRecorder.cpp.incl"
00029
00030
00031
00032
00033
00034 # define INITIAL_ARG_SIZE 5
00035 # define INITIAL_TEMP_SIZE 5
00036 # define INITIAL_CONTEXT_TEMP_SIZE 5
00037 # define INITIAL_EXPR_STACK_SIZE 10
00038
00039 # define INITIAL_OOPS_SIZE 100
00040 # define INITIAL_VALUES_SIZE 100
00041 # define INITIAL_DEPENDANTS_SIZE 20
00042 # define INITIAL_CONTEXT_SCOPE_ARRAY_SIZE 10
00043
00044 const u_char nameDescHeaderByte::code_width = 2;
00045 const u_char nameDescHeaderByte::index_width = 5;
00046 const u_char nameDescHeaderByte::is_last_bit_num = code_width+index_width;
00047 const u_char nameDescHeaderByte::max_code = nthMask(code_width);
00048
00049 const u_char nameDescHeaderByte::max_index = nthMask(index_width) - 3;
00050 const u_char nameDescHeaderByte::no_index = nthMask(index_width) - 2;
00051 const u_char nameDescHeaderByte::termination_index = nthMask(index_width) - 1;
00052 const u_char nameDescHeaderByte::illegal_index = nthMask(index_width) - 0;
00053
00054
00055
00056
00057
00058
00059
00060
00061 const u_char scopeDescHeaderByte::code_width = 2;
00062 const u_char scopeDescHeaderByte::max_code = nthMask(code_width);
00063 const u_char scopeDescHeaderByte::lite_bit_num = code_width;
00064 const u_char scopeDescHeaderByte::args_bit_num = code_width+1;
00065 const u_char scopeDescHeaderByte::temps_bit_num = code_width+2;
00066 const u_char scopeDescHeaderByte::context_temps_bit_num = code_width+3;
00067 const u_char scopeDescHeaderByte::expr_stack_bit_num = code_width+4;
00068 const u_char scopeDescHeaderByte::context_bit_num = code_width+5;
00069
00070
00071
00072
00073
00074 class LogicalAddress : public ResourceObj {
00075 private:
00076 NameNode* _physical_address;
00077 int _pc_offset;
00078 LogicalAddress* _next;
00079 int _offset;
00080
00081 NameNode* physical_address() const { return _physical_address; }
00082 int pc_offset() const { return _pc_offset; }
00083 LogicalAddress* next() const { return _next; }
00084 public:
00085 LogicalAddress(NameNode* physical_address, int pc_offset = 0);
00086
00087 void append(NameNode* physical_address, int pc_offset);
00088 NameNode* physical_address_at(int pc_offset);
00089 void generate(ScopeDescRecorder* rec);
00090
00091 int length();
00092 };
00093
00094
00095 LogicalAddress::LogicalAddress(NameNode* physical_address, int pc_offset) {
00096 _physical_address = physical_address;
00097 _pc_offset = pc_offset;
00098 _next = NULL;
00099 _offset = -1;
00100 }
00101
00102 void LogicalAddress::append(NameNode* physical_address, int pc_offset) {
00103 if (next()) {
00104
00105 next()->append(physical_address, pc_offset);
00106 } else {
00107 assert(_pc_offset <= pc_offset, "checking progress");
00108 _next = new LogicalAddress(physical_address, pc_offset);
00109 }
00110 }
00111
00112 NameNode* LogicalAddress::physical_address_at(int pc_offset) {
00113 LogicalAddress* current = this;
00114 while (current->next() && current->next()->pc_offset() > pc_offset) {
00115 current = current->next();
00116 }
00117 return current->physical_address();
00118 }
00119
00120 int LogicalAddress::length() {
00121 LogicalAddress* current = this;
00122 int result = 1;
00123 while (current->next()) {
00124 current = current->next();
00125 result++;
00126 }
00127 return result;
00128 }
00129
00130 void LogicalAddress::generate(ScopeDescRecorder* rec) {
00131
00132
00133
00134
00135 LogicalAddress* n = next();
00136 physical_address()->generate(rec, n == NULL);
00137
00138 int last_pc_offset = 0;
00139 while (n != NULL) {
00140 LogicalAddress* current = n;
00141 n = n->next();
00142 current->physical_address()->generate(rec, n == NULL);
00143 assert(last_pc_offset <= current->pc_offset(), "checking progress");
00144 rec->genValue(current->pc_offset() - last_pc_offset);
00145 last_pc_offset = current->pc_offset();
00146 }
00147 }
00148
00149 class Array: public ResourceObj {
00150 private:
00151 int index;
00152 int size;
00153
00154 int offset;
00155
00156 int* values;
00157 public:
00158 Array(int size);
00159
00160 int length() { return index; }
00161 void extend(int newSize);
00162 int insertIfAbsent(int value);
00163 void copy_to(int*& addr);
00164 };
00165
00166 class ByteArray : public ResourceObj {
00167 private:
00168 u_char* array;
00169 int top;
00170 int max;
00171
00172 void extend();
00173
00174 public:
00175 int size() { return top; }
00176 u_char* start() { return array; }
00177
00178 ByteArray(int size);
00179
00180 void appendByte(u_char p) {
00181 if (top + (int) sizeof(u_char) > max) extend();
00182 array[top++] = p;
00183 }
00184
00185 void appendHalf(int16 p);
00186 #ifdef UNUSED
00187 void appendWord(int p);
00188 #endif
00189
00190 void putByteAt(u_char p, int offset) {
00191 assert( offset < max, "index out of bound");
00192 array[offset] = p;
00193 }
00194
00195 void putHalfAt(int16 p, int offset);
00196
00197
00198 void setTop(int offset) {
00199 assert( this->top >= offset, "A smaller top is expected");
00200 this->top = offset;
00201 }
00202
00203 void alignToWord();
00204 void copy_to(int*& addr);
00205 };
00206
00207 NameNode* newValueName(oop value) {
00208 if (value->is_block()) {
00209 fatal("should never be a block");
00210 return NULL;
00211 } else {
00212 return new ValueName(value);
00213 }
00214 }
00215
00216 bool NameNode::genHeaderByte(ScopeDescRecorder* rec, u_char code, bool is_last, int index) {
00217
00218
00219
00220
00221 nameDescHeaderByte b;
00222 bool can_inline = index <= b.max_index;
00223 u_char coded_index = can_inline ? index : b.no_index;
00224 b.pack(code, is_last, coded_index);
00225 rec->codes->appendByte( b.value());
00226 return can_inline;
00227 }
00228
00229 inline int ScopeDescRecorder::getValueIndex(int v) {
00230
00231 if ( 0 <= v && v <= MAX_INLINE_VALUE) return v;
00232 return MAX_INLINE_VALUE + 1 + values->insertIfAbsent(v);
00233 }
00234
00235 inline int ScopeDescRecorder::getOopIndex(oop o) {
00236 return o == 0 ? 0 : oops->insertIfAbsent((int)o) + 1;
00237 }
00238
00239 void ScopeDescRecorder::emit_illegal_node(bool is_last) {
00240 nameDescHeaderByte b;
00241 b.pack_illegal(is_last);
00242 codes->appendByte(b.value());
00243 }
00244
00245 void ScopeDescRecorder::emit_termination_node() {
00246 nameDescHeaderByte b;
00247 b.pack_termination(true);
00248 codes->appendByte(b.value());
00249 }
00250
00251 void IllegalName::generate(ScopeDescRecorder* rec, bool is_last) {
00252 rec->emit_illegal_node(is_last);
00253 }
00254
00255
00256 static ScopeDesc* _sd;
00257 static nmethodScopes* _scopes;
00258 static ScopeDesc* _getNextScopeDesc() {
00259 _sd = _scopes->getNext(_sd);
00260 if (!_sd) fatal("out of scopeDescs");
00261 return _sd;
00262 }
00263
00264 Array::Array(int sz) {
00265 size = sz;
00266 index = 0;
00267 values = NEW_RESOURCE_ARRAY(int, sz);
00268 }
00269
00270 int Array::insertIfAbsent(int value){
00271 for (int i = 0; i < index; i ++)
00272 if (values[i] == value)
00273 return i;
00274 if (index == size)
00275 extend(size*2);
00276 values[index] = value;
00277 return index++;
00278 }
00279
00280 void Array::extend(int newSize) {
00281 int* newValues = NEW_RESOURCE_ARRAY(int, newSize);
00282 for(int i=0;i < index; i++)
00283 newValues[i] = values[i];
00284 values = newValues;
00285 size = newSize;
00286 }
00287
00288 void Array::copy_to(int*& addr) {
00289 for(int i=0;i < length(); i++) {
00290 *addr++ = values[i];
00291 }
00292 }
00293
00294 ByteArray::ByteArray(int size) {
00295 array = NEW_RESOURCE_ARRAY(u_char, size);
00296 max = size;
00297 top = 0;
00298 }
00299
00300 void ByteArray::extend() {
00301 int newMax = max*2;
00302 u_char* newArray = NEW_RESOURCE_ARRAY(u_char, newMax);
00303 for(int i=0;i < top; i++)
00304 newArray[i] = array[i];
00305 array = newArray;
00306 max = newMax;
00307 }
00308
00309 void ByteArray::appendHalf(int16 p) {
00310 if (top + (int) sizeof(int16) > max) extend();
00311
00312 array[top++] = p >> BYTE_WIDTH;
00313 array[top++] = (u_char)lowerBits(p, 8);
00314 }
00315
00316 void ByteArray::putHalfAt(int16 p, int offset) {
00317
00318 array[offset ] = p >> BYTE_WIDTH;
00319 array[offset+1] = (u_char)lowerBits(p, 8);
00320 }
00321
00322 #ifdef UNUSED
00323 void ByteArray::appendWord(int p) {
00324 if (top+sizeof(int) > max) extend();
00325 assert( size() % sizeof(int) == 0, "Not word aligned");
00326 int* s = (int*) &array[top];
00327 *s = p;
00328 top += sizeof(int);
00329 }
00330 #endif
00331
00332 void ByteArray::alignToWord() {
00333 int fill_size = (sizeof(int) - (size()%sizeof(int))) % sizeof(int);
00334 for(int i = 0; i < fill_size; i++)
00335 appendByte(0);
00336 }
00337
00338 void ByteArray::copy_to(int*& addr) {
00339 int* fromAddr = (int*) start();
00340 int len = size()/sizeof(int);
00341 for(int i=0;i < len; i++) {
00342 *addr++ = *fromAddr++;
00343 }
00344 }
00345
00346
00347
00348
00349
00350
00351
00352 # define INVALID_OFFSET -1
00353
00354 class ScopeDescNode: public ResourceObj {
00355 public:
00356 methodOop method;
00357 bool allocates_compiled_context;
00358 int scopeID;
00359 bool lite;
00360 int senderBCI;
00361 bool visible;
00362
00363 GrowableArray<LogicalAddress*>* arg_list;
00364 GrowableArray<LogicalAddress*>* temp_list;
00365 GrowableArray<LogicalAddress*>* context_temp_list;
00366 GrowableArray<LogicalAddress*>* expr_stack_list;
00367
00368 int offset;
00369
00370
00371 bool usedInPcs;
00372
00373 public:
00374 bool has_args() const { return !lite && !arg_list->isEmpty(); }
00375 bool has_temps() const { return !lite && !temp_list->isEmpty(); }
00376 bool has_context_temps() const { return !lite && !context_temp_list->isEmpty(); }
00377 bool has_expr_stack() const { return !lite && !expr_stack_list->isEmpty(); }
00378 bool has_context() const { return allocates_compiled_context; }
00379
00380 bool has_nameDescs() const { return has_args()
00381 || has_temps()
00382 || has_context_temps()
00383 || has_expr_stack(); }
00384
00385 ScopeInfo scopesHead;
00386 ScopeInfo scopesTail;
00387 ScopeInfo next;
00388
00389 ScopeDescNode(methodOop method, bool allocates_compiled_context, int scopeID, bool lite, int senderBCI, bool visible);
00390
00391 void addNested(ScopeInfo scope);
00392
00393 virtual u_char code() = 0;
00394
00395 virtual void generate(ScopeDescRecorder* rec, int senderScopeOffset, bool bigHeader);
00396 void generateBody(ScopeDescRecorder* rec, int senderScopeOffset);
00397 void generateNameDescs(ScopeDescRecorder* rec);
00398
00399 void generate_solid(GrowableArray<LogicalAddress*>* list, ScopeDescRecorder* rec);
00400 void generate_sparse(GrowableArray<LogicalAddress*>* list, ScopeDescRecorder* rec);
00401
00402 bool computeVisibility();
00403
00404 ScopeInfo find_scope(int scope_id);
00405
00406 virtual void verify(ScopeDesc* sd);
00407 void verifyBody();
00408 };
00409
00410 ScopeInfo ScopeDescNode::find_scope(int scope_id) {
00411 if (scopeID == scope_id) return this;
00412 for(ScopeInfo p = scopesHead; p != NULL; p = p->next) {
00413 ScopeInfo result = p->find_scope(scope_id);
00414 if (result) return result;
00415 }
00416 return NULL;
00417 }
00418
00419 void ScopeDescNode::generate_solid(GrowableArray<LogicalAddress*>* list, ScopeDescRecorder* rec) {
00420
00421 for(int i = 0; i < list->length(); i++) {
00422 assert(list->at(i), "must be a solid array");
00423 list->at(i)->generate(rec);
00424 }
00425
00426 rec->emit_termination_node();
00427 }
00428
00429 void ScopeDescNode::generate_sparse(GrowableArray<LogicalAddress*>* list, ScopeDescRecorder* rec) {
00430
00431 for(int i = 0; i < list->length(); i++) {
00432 if (list->at(i)) {
00433 list->at(i)->generate(rec);
00434 rec->genValue(i);
00435 }
00436 }
00437
00438 rec->emit_termination_node();
00439 }
00440
00441 struct PcDescNode: public ResourceObj {
00442 int pcOffset;
00443 ScopeInfo scope;
00444 int bci;
00445 };
00446
00447 class PcDescInfoClass : public ResourceObj {
00448 protected:
00449 PcDescNode* nodes;
00450 int end;
00451 int size;
00452 public:
00453 PcDescInfoClass(int size);
00454 int length() { return end; }
00455 void extend(int newSize);
00456 void add(int pcOffset, ScopeInfo scope, int bci);
00457 void mark_scopes();
00458 void copy_to(int*& addr);
00459 };
00460
00461 ScopeDescNode::ScopeDescNode(methodOop method, bool allocates_compiled_context, int scopeID, bool lite, int senderBCI, bool visible) {
00462 this->scopeID = scopeID;
00463 this->method = method;
00464 this->lite = lite;
00465 this->senderBCI = senderBCI;
00466 this->visible = visible;
00467 this->allocates_compiled_context = allocates_compiled_context;
00468
00469 arg_list = new GrowableArray<LogicalAddress*>(INITIAL_ARG_SIZE);
00470 temp_list = new GrowableArray<LogicalAddress*>(INITIAL_TEMP_SIZE);
00471 context_temp_list = new GrowableArray<LogicalAddress*>(INITIAL_CONTEXT_TEMP_SIZE);
00472 expr_stack_list = new GrowableArray<LogicalAddress*>(INITIAL_EXPR_STACK_SIZE);
00473
00474 offset = INVALID_OFFSET;
00475 scopesHead = NULL;
00476 scopesTail = NULL;
00477 usedInPcs = false;
00478 }
00479
00480 void ScopeDescNode::addNested(ScopeInfo scope) {
00481 scope->next = NULL;
00482 if (scopesHead == NULL) {
00483 scopesHead = scopesTail = scope;
00484 } else {
00485 scopesTail->next = scope;
00486 scopesTail = scope;
00487 }
00488 }
00489
00490 void ScopeDescNode::generate(ScopeDescRecorder* rec, int senderScopeOffset, bool bigHeader) {
00491 offset = rec->codes->size();
00492
00493 rec->genScopeDescHeader(code(), lite, has_args(), has_temps(), has_context_temps(), has_expr_stack(), has_context(), bigHeader);
00494 if (offset != 0) {
00495
00496 rec->genValue(offset - senderScopeOffset);
00497 rec->genValue(senderBCI);
00498 }
00499 rec->genOop(method);
00500 rec->genValue(scopeID);
00501 }
00502
00503 void ScopeDescNode::generateNameDescs(ScopeDescRecorder* rec) {
00504 assert(has_nameDescs(), "must have nameDescs");
00505 if (has_args()) generate_solid(arg_list, rec);
00506 if (has_temps()) generate_solid(temp_list, rec);
00507 if (has_context_temps()) generate_solid(context_temp_list, rec);
00508 if (has_expr_stack()) generate_sparse(expr_stack_list, rec);
00509 }
00510
00511 void ScopeDescNode::generateBody(ScopeDescRecorder* rec, int senderScopeOffset) {
00512 if (has_nameDescs()) {
00513 generateNameDescs(rec);
00514 if (!rec->updateScopeDescHeader(offset, rec->codes->size())) {
00515
00516
00517
00518 rec->codes->setTop(offset);
00519 generate(rec, senderScopeOffset, true);
00520 generateNameDescs(rec);
00521 rec->updateExtScopeDescHeader(offset, rec->codes->size());
00522 }
00523 }
00524
00525 for(ScopeInfo p = scopesHead; p != NULL; p = p->next) {
00526 if (p->visible) {
00527 p->generate(rec, offset, false);
00528 p->generateBody(rec, offset);
00529 }
00530 }
00531 }
00532
00533 void ScopeDescNode::verify(ScopeDesc* sd) {
00534 if (senderBCI != IllegalBCI && senderBCI != sd->senderBCI()) fatal("senderBCI is wrong");
00535 }
00536
00537 void ScopeDescNode::verifyBody() {
00538 for(ScopeInfo p = scopesHead; p != NULL; p = p->next) {
00539 if (p->visible) {
00540 p->verify(_getNextScopeDesc());
00541 p->verifyBody();
00542 }
00543 }
00544 }
00545
00546 bool ScopeDescNode::computeVisibility() {
00547 visible = false;
00548 for(ScopeInfo p = scopesHead; p != NULL; p = p->next) {
00549 visible = p->computeVisibility() || visible;
00550 }
00551 visible = visible || (usedInPcs && GenerateLiteScopeDescs) || !lite;
00552 return visible;
00553 }
00554
00555
00556 class MethodScopeNode: public ScopeDescNode {
00557 public:
00558 LookupKey* key;
00559 LogicalAddress* receiver_location;
00560
00561 u_char code() { return METHOD_CODE; }
00562
00563 MethodScopeNode(LookupKey* key,
00564 methodOop method,
00565 LogicalAddress* receiver_location,
00566 bool allocates_compiled_context,
00567 bool lite,
00568 int scopeID,
00569 int senderBCI,
00570 bool visible)
00571 : ScopeDescNode(method, allocates_compiled_context, scopeID, lite, senderBCI, visible) {
00572 this->key = key;
00573 this->receiver_location = receiver_location;
00574 }
00575
00576 void generate(ScopeDescRecorder* rec, int senderScopeOffset, bool bigHeader);
00577
00578 void verify(ScopeDesc* sd);
00579 };
00580
00581
00582 void MethodScopeNode::generate(ScopeDescRecorder* rec,
00583 int senderScopeOffset, bool bigHeader) {
00584 ScopeDescNode::generate(rec,senderScopeOffset, bigHeader);
00585 rec->genOop(key->klass());
00586 rec->genOop(key->selector_or_method());
00587 receiver_location->generate(rec);
00588 }
00589
00590 void MethodScopeNode::verify(ScopeDesc* sd) {
00591 ScopeDescNode::verify(sd);
00592 if (!sd->isMethodScope()) fatal("MethodScope expected");
00593 }
00594
00595 class TopLevelBlockScopeNode: public ScopeDescNode {
00596 public:
00597 LogicalAddress* receiver_location;
00598 klassOop receiver_klass;
00599
00600 u_char code() { return TOPLEVELBLOCK_CODE; }
00601
00602 TopLevelBlockScopeNode(methodOop method, LogicalAddress* receiver_location, klassOop receiver_klass, bool allocates_compiled_context)
00603 : ScopeDescNode(method, allocates_compiled_context, false, 0, NULL, true) {
00604 this->receiver_location = receiver_location;
00605 this->receiver_klass = receiver_klass;
00606 }
00607
00608 void generate(ScopeDescRecorder* rec, int senderScopeOffset, bool bigHeader) {
00609 ScopeDescNode::generate(rec, senderScopeOffset, bigHeader);
00610 receiver_location->generate(rec);
00611 rec->genOop(receiver_klass);
00612 }
00613
00614 void verify(ScopeDesc* sd) {
00615 ScopeDescNode::verify(sd);
00616 if (!sd->isTopLevelBlockScope()) fatal("TopLevelBlockScope expected");
00617 }
00618 };
00619
00620 class BlockScopeNode: public ScopeDescNode {
00621 public:
00622 ScopeInfo parent;
00623
00624 BlockScopeNode(methodOop method,
00625 ScopeInfo parent,
00626 bool allocates_compiled_context,
00627 bool lite,
00628 int scopeID,
00629 int senderBCI,
00630 bool visible)
00631 : ScopeDescNode(method, allocates_compiled_context, scopeID, lite, senderBCI, visible) {
00632 this->parent = parent;
00633 }
00634
00635 u_char code() { return BLOCK_CODE; }
00636
00637 void generate(ScopeDescRecorder* rec, int senderScopeOffset, bool bigHeader);
00638
00639 void verify(ScopeDesc* sd);
00640 };
00641
00642 void BlockScopeNode::generate(ScopeDescRecorder* rec, int senderScopeOffset, bool bigHeader) {
00643 ScopeDescNode::generate(rec, senderScopeOffset, bigHeader);
00644 rec->genValue(offset - parent->offset);
00645 }
00646
00647 void BlockScopeNode::verify(ScopeDesc* sd) {
00648 ScopeDescNode::verify(sd);
00649 }
00650
00651 class NonInlinedBlockScopeNode: public ResourceObj {
00652 public:
00653 int offset;
00654 NonInlinedBlockScopeNode* next;
00655 methodOop method;
00656 ScopeInfo parent;
00657
00658 NonInlinedBlockScopeNode(methodOop method, ScopeInfo parent) {
00659 this->method = method;
00660 this->parent = parent;
00661 this->offset = INVALID_OFFSET;
00662 this->next = NULL;
00663 }
00664 u_char code() { return NONINLINED_BLOCK_CODE; }
00665 void generate(ScopeDescRecorder* rec);
00666 };
00667
00668 void NonInlinedBlockScopeNode::generate(ScopeDescRecorder* rec) {
00669 offset = rec->codes->size();
00670 rec->genScopeDescHeader(code(), false, false, false, false, false, false, false);
00671 rec->genOop(method);
00672 rec->genValue(offset - parent->offset);
00673
00674 }
00675
00676 void ScopeDescRecorder::generate() {
00677 assert(root, "root scope must be present");
00678
00679
00680 generateDependencies();
00681
00682 pcs->mark_scopes();
00683 (void) root->computeVisibility();
00684 root->generate(this, 0, false);
00685 root->generateBody(this, 0);
00686
00687 for(NonInlinedBlockScopeNode* p = nonInlinedBlockScopesHead; p != NULL; p = p->next) {
00688 p->generate(this);
00689 }
00690
00691 codes->alignToWord();
00692 _hasCodeBeenGenerated = true;
00693 }
00694
00695 void ScopeDescRecorder::generateDependencies() {
00696 int end_marker = 0;
00697 for (int index = 0; index < dependants->length(); index++) {
00698 int i = oops->insertIfAbsent((int)dependants->at(index));
00699 if (i > end_marker) end_marker = i;
00700 }
00701 dependants_end = end_marker;
00702 }
00703
00704 ScopeInfo ScopeDescRecorder::addScope(ScopeInfo scope, ScopeInfo senderScope){
00705 if (root == NULL) {
00706 assert( senderScope == NULL, "Root scope must be the first");
00707 root = scope;
00708 } else {
00709 assert( senderScope != NULL, "Sender scope must be present");
00710 senderScope->addNested(scope);
00711 }
00712 return scope;
00713 }
00714
00715 NonInlinedBlockScopeNode* ScopeDescRecorder::addNonInlinedBlockScope(NonInlinedBlockScopeNode* scope) {
00716 scope->next = NULL;
00717 if (nonInlinedBlockScopesHead == NULL) {
00718 nonInlinedBlockScopesHead = nonInlinedBlockScopesTail = scope;
00719 } else {
00720 nonInlinedBlockScopesTail->next = scope;
00721 nonInlinedBlockScopesTail = scope;
00722 }
00723 return scope;
00724 }
00725
00726 int ScopeDescRecorder::offset(ScopeInfo scope) {
00727 assert(scope->offset != INVALID_OFFSET, "uninitialized offset");
00728 return scope->offset;
00729 }
00730
00731 int ScopeDescRecorder::offset_for_noninlined_scope_node(NonInlinedBlockScopeNode* scope) {
00732 assert(scope->offset != INVALID_OFFSET, "uninitialized offset");
00733 return scope->offset;
00734 }
00735
00736 ScopeInfo ScopeDescRecorder::addMethodScope(LookupKey* key,
00737 methodOop method,
00738 LogicalAddress* receiver_location,
00739 bool allocates_compiled_context,
00740 bool lite,
00741 int scopeID,
00742 ScopeInfo senderScope,
00743 int senderBCI,
00744 bool visible) {
00745 return addScope(
00746 new MethodScopeNode(key, method, receiver_location, allocates_compiled_context, lite, scopeID, senderBCI, visible),
00747 senderScope);
00748 }
00749
00750
00751 ScopeInfo ScopeDescRecorder::addBlockScope(methodOop method,
00752 ScopeInfo parent,
00753 bool allocates_compiled_context,
00754 bool lite,
00755 int scopeID,
00756 ScopeInfo senderScope,
00757 int senderBCI,
00758 bool visible) {
00759 return addScope(
00760 new BlockScopeNode(method, parent, allocates_compiled_context, lite, scopeID, senderBCI, visible),
00761 senderScope);
00762 }
00763
00764 ScopeInfo ScopeDescRecorder::addTopLevelBlockScope(methodOop method,
00765 LogicalAddress* receiver_location,
00766 klassOop receiver_klass,
00767 bool allocates_compiled_context) {
00768 return addScope(new TopLevelBlockScopeNode(method, receiver_location, receiver_klass, allocates_compiled_context), NULL);
00769 }
00770
00771 NonInlinedBlockScopeNode* ScopeDescRecorder::addNonInlinedBlockScope(methodOop method, ScopeInfo parent) {
00772
00773 return addNonInlinedBlockScope(new NonInlinedBlockScopeNode(method, parent));
00774 }
00775
00776
00777 void ScopeDescRecorder::addArgument(ScopeInfo scope, int index, LogicalAddress* location){
00778 assert(!scope->lite, "cannot add slot to lite scopeDesc");
00779 scope->arg_list->at_put_grow(index, location);
00780 }
00781
00782 void ScopeDescRecorder::addTemporary(ScopeInfo scope, int index, LogicalAddress* location){
00783 assert(!scope->lite, "cannot add slot to lite scopeDesc");
00784 scope->temp_list->at_put_grow(index, location);
00785 }
00786
00787 void ScopeDescRecorder::addExprStack(ScopeInfo scope, int index, LogicalAddress* location) {
00788 assert(!scope->lite, "cannot add expression to lite scopeDesc");
00789 scope->expr_stack_list->at_put_grow(index, location);
00790 }
00791
00792 void ScopeDescRecorder::addContextTemporary(ScopeInfo scope, int index, LogicalAddress* location) {
00793 assert(!scope->lite, "cannot add expression to lite scopeDesc");
00794 scope->context_temp_list->at_put_grow(index, location);
00795 }
00796
00797 LogicalAddress* ScopeDescRecorder::createLogicalAddress(NameNode* initial_value) {
00798 return new LogicalAddress(initial_value);
00799 }
00800
00801 void ScopeDescRecorder::changeLogicalAddress(LogicalAddress* location, NameNode* new_value, int pc_offset) {
00802 location->append(new_value, pc_offset);
00803 }
00804
00805 void ScopeDescRecorder::genScopeDescHeader(u_char code,
00806 bool lite,
00807 bool args,
00808 bool temps,
00809 bool context_temps,
00810 bool expr_stack,
00811 bool has_context,
00812 bool bigHeader) {
00813 scopeDescHeaderByte b;
00814 b.pack(code, lite, args, temps, context_temps, expr_stack, has_context);
00815 codes->appendByte(b.value());
00816 if (b.has_nameDescs()) {
00817 codes->appendByte(0);
00818 if (bigHeader) {
00819 codes->appendHalf(0);
00820 }
00821 }
00822 }
00823
00824 int ScopeDescRecorder::updateScopeDescHeader(int offset, int next) {
00825 int nextIndex = getValueIndex(next - offset);
00826 if (nextIndex < EXTENDED_INDEX) {
00827 codes->putByteAt(nextIndex, offset+1);
00828 return true;
00829 } else {
00830 return false;
00831 }
00832 }
00833
00834 void ScopeDescRecorder::updateExtScopeDescHeader(int offset, int next) {
00835 int nextIndex = getValueIndex(next - offset);
00836 codes->putByteAt(EXTENDED_INDEX, offset+1);
00837 codes->putHalfAt(nextIndex, offset+2);
00838 }
00839
00840 inline void ScopeDescRecorder::genIndex(int index) {
00841 if (index < EXTENDED_INDEX) {
00842
00843 codes->appendByte(index);
00844 } else {
00845 codes->appendByte(EXTENDED_INDEX);
00846 codes->appendHalf(index);
00847 }
00848 }
00849
00850 void ScopeDescRecorder::genValue(int v) {
00851 genIndex(getValueIndex(v));
00852 }
00853
00854 void ScopeDescRecorder::genOop(oop o) {
00855 genIndex(getOopIndex(o));
00856 }
00857
00858 PcDescInfoClass::PcDescInfoClass(int sz) {
00859 nodes = NEW_RESOURCE_ARRAY(PcDescNode, sz);
00860 end = 0;
00861 size = sz;
00862 }
00863
00864 void PcDescInfoClass::extend(int newSize) {
00865 PcDescNode* newNodes = NEW_RESOURCE_ARRAY(PcDescNode, newSize);
00866 for(int i=0;i < end; i++)
00867 newNodes[i] = nodes[i];
00868 nodes = newNodes;
00869 size = newSize;
00870 }
00871
00872 void PcDescInfoClass::add(int pcOffset, ScopeInfo scope, int bci) {
00873 if (scope->lite && !GenerateLiteScopeDescs) return;
00874 if (end == size) extend(size*2);
00875
00876
00877
00878 while (end > 0 && pcOffset < nodes[end-1].pcOffset) {
00879 end--;
00880 }
00881
00882 if (CompressPcDescs && end > 0) {
00883
00884 if (scope == nodes[end-1].scope && bci == nodes[end-1].bci) return;
00885
00886 if (pcOffset == nodes[end-1].pcOffset) {
00887 end--;
00888 }
00889 }
00890
00891 nodes[end].pcOffset = pcOffset;
00892 nodes[end].scope = scope;
00893 nodes[end].bci = bci;
00894 end++;
00895 }
00896
00897 void PcDescInfoClass::mark_scopes() {
00898 for(int i=0;i < end; i++) {
00899 if (nodes[i].scope) nodes[i].scope->usedInPcs = true;
00900 }
00901 }
00902
00903 void PcDescInfoClass::copy_to(int*& addr) {
00904 for(int i = 0; i < end; i++) {
00905 PcDesc* pc = (PcDesc*) addr;
00906 pc->pc = nodes[i].pcOffset;
00907 pc->scope = nodes[i].scope ? nodes[i].scope->offset : IllegalBCI;
00908 pc->byteCode = nodes[i].bci;
00909 addr += sizeof(PcDesc)/sizeof(int);
00910 }
00911 }
00912
00913 void LocationName::generate(ScopeDescRecorder* rec, bool is_last) {
00914 Location converted_location = rec->convert_location(l);
00915 int index = rec->getValueIndex(converted_location._loc);
00916 if (!genHeaderByte(rec, LOCATION_CODE, is_last, index)) rec->genIndex(index);
00917 }
00918
00919 void ValueName::generate(ScopeDescRecorder* rec, bool is_last) {
00920 int index = rec->getOopIndex(value);
00921 if (!genHeaderByte(rec, VALUE_CODE, is_last, index)) rec->genIndex(index);
00922 }
00923
00924 void MemoizedName::generate(ScopeDescRecorder* rec, bool is_last) {
00925 Location converted_location = rec->convert_location(loc);
00926 int index = rec->getValueIndex(converted_location._loc);
00927 if (!genHeaderByte(rec, MEMOIZEDBLOCK_CODE, is_last, index)) rec->genIndex(index);
00928 rec->genOop(oop(block_method));
00929 rec->genValue(parent_scope == NULL ? 0 : parent_scope->offset);
00930 }
00931
00932 void BlockValueName::generate(ScopeDescRecorder* rec, bool is_last) {
00933 int index = rec->getOopIndex(oop(block_method));
00934 if (!genHeaderByte(rec, BLOCKVALUE_CODE, is_last, index)) rec->genIndex(index);
00935 rec->genValue(parent_scope == NULL ? 0 : parent_scope->offset);
00936 }
00937
00938 Location ScopeDescRecorder::convert_location(Location loc) {
00939 if (!loc.isContextLocation()) return loc;
00940 int scope_id = loc.scopeID();
00941
00942
00943 ScopeInfo scope = theCompiler->scopes->at(scope_id)->scopeInfo();
00944 assert(scope, "scope must exist");
00945 if (scope->offset == INVALID_OFFSET) {
00946 std->print_cr(loc.name());
00947 theCompiler->print_code(false);
00948 fatal("compiler error: context location appears outside its scope");
00949 }
00950 return Location::runtimeContextLocation(loc.contextNo(), loc.tempNo(), scope->offset);
00951 }
00952
00953
00954 int ScopeDescRecorder::size() {
00955 return sizeof(nmethodScopes)
00956 + codes->size()
00957 + oops->length() * sizeof(oop)
00958 + values->length() * sizeof(int)
00959 + pcs->length() * sizeof(PcDesc);
00960 }
00961
00962 ScopeDescRecorder::ScopeDescRecorder(int byte_size, int pcDesc_size) {
00963
00964 root = NULL;
00965 oops = new Array(INITIAL_OOPS_SIZE);
00966 values = new Array(INITIAL_VALUES_SIZE);
00967 codes = new ByteArray(byte_size);
00968 pcs = new PcDescInfoClass(pcDesc_size);
00969
00970 dependants = new GrowableArray<klassOop>(INITIAL_DEPENDANTS_SIZE);
00971
00972 _hasCodeBeenGenerated = false;
00973
00974 nonInlinedBlockScopesHead = NULL;
00975 nonInlinedBlockScopesTail = NULL;
00976 }
00977
00978 void ScopeDescRecorder::copyTo(nmethod* nm) {
00979 { nmethodScopes* d = (nmethodScopes*) nm->scopes();
00980 bool update = false;
00981
00982
00983 int* start = (int*)(d+1);
00984 int* p = start;
00985
00986 d->set_nmethod_offset((char*) d - (char*) nm);
00987
00988 codes->copy_to( p);
00989
00990 d->set_oops_offset((char*) p - (char*) start);
00991 oops->copy_to( p);
00992
00993 d->set_value_offset((char*) p - (char*) start);
00994 values->copy_to( p);
00995
00996 d->set_pcs_offset((char*) p - (char*) start);
00997 pcs->copy_to( p);
00998
00999 d->set_length((char*) p - (char*) start);
01000
01001 d->set_dependants_end(dependants_end);
01002
01003 assert( (char*) d + size() == (char*) p, "wrong size of nmethodScopes");
01004 }
01005 }
01006
01007 void ScopeDescRecorder::addPcDesc(int pcOffset, ScopeInfo scope, int bci) {
01008 assert( scope, "scope must be specified in addPcDesc");
01009 assert( root, "root must be present");
01010 pcs->add(pcOffset, scope, bci);
01011 }
01012
01013 void ScopeDescRecorder::add_dependant(LookupKey* key) {
01014
01015 dependants->append(key->klass());
01016 }
01017
01018
01019 void ScopeDescRecorder::verify(nmethodScopes* scopes) {
01020
01021 _scopes = scopes;
01022 _sd = NULL;
01023
01024 assert( root, "root must be present to verify");
01025 root->verify(_getNextScopeDesc());
01026 root->verifyBody();
01027 }
01028
01029 #endif