void ScopeLookupKey::print() { if (delegatee != NULL) { if (delegatee->is_string()) { stringOop(delegatee)->string_print(); } else { delegatee->print_real_oop(); } lprintf("."); } if (selector->is_string()) { stringOop(selector)->string_print(); } else { selector->print_real_oop(); } }
const char* selector_string(oop selector) { if (selector->is_string()) { return stringOop(selector)->copy_null_terminated(); } else { return "<not a string>"; } }
bool compilingLookup::isSelectorInCompileWithSICNames(oop selector) { objVectorOop names = (objVectorOop)CompileWithSICNames; for (fint i = names->length() - 1; i >= 0; --i) { if (selector == names->obj_at(i)) { lprintf("\n\n<<< SIC-compiling \"%s\" (Reason: CompileWithSICNames) >>>\n\n", stringOop(selector)->copy_null_terminated()); return true; } } return false; }
// If you change the names or number of blocks slots, // change blockMap::find_slot too. void slotIterator_init() { // block parent slot block_slots[0].name= VMString[PARENT]; block_slots[0].type= parent_map_slotType; block_slots[0].data= Memory->blockTraitsObj; block_slots[0].annotation= Memory->slotAnnotationObj; // used and reused for value, value:, value:With:, etc.. block_slots[1].name= stringOop(badOop); block_slots[1].type= map_slotType; block_slots[1].data= badOop; block_slots[1].annotation= Memory->slotAnnotationObj; }
ResultType realSlotRef::resultType(oop sel) { if (desc->is_arg_slot()) return dataResult; if (desc->is_map_slot()) { if (desc->data->has_code()) { // not sure why this is here, compiler uses it (dmu) ((objectLookupTarget*) holder)->value_constrained = true; return methodResult; } return constantResult; } if (stringOop(sel)->is_1arg_keyword()) return assignmentResult; else return dataResult; }
void vframeMap::print(oop obj) { ResourceMark rm; lprintf("vframe "); if (WizardMode && !obj->is_map()) { vframeOop vfo = vframeOop(obj); if (vfo->is_live()) { abstract_vframe* vf = vfo->as_vframe(); const char* sel = vf->selector() ? stringOop(vf->selector())->copy_null_terminated() : "..."; lprintf("(%s / %#lx %#lx) ", sel, vfo->fr(), vfo->locals()); } else { lprintf("(DEAD)"); } } slotsMapDeps::print(obj); }
stringOop blockOopClass::outermostMethodSelector() { oop selector = NULL; for ( abstract_vframe* pp = parentVFrame(NULL, true); pp != NULL; pp = pp->parent()) selector = pp->selector(); if (selector == NULL) { // block was zapped /* should really get name from lexical linkes here's a start: slotsOop v = value(); if (v->map()->has_code()) { slotsOop ll = v->map()->get_lexical_link(); .... */ selector = new_string("zappedBlock"); } assert_string(selector, "should be a selector"); return stringOop(selector); }
void vframeMap::print_oop(oop obj) { bool live = vframeOop(obj)->is_live(); lprintf("<a%s activation object", live ? "n" : " dead"); if (WizardMode && live) { ResourceMark rm; abstract_vframe* vf = vframeOop(obj)->as_vframe(); # if defined(FAST_COMPILER) || defined(SIC_COMPILER) if (vf->is_compiled()) { compiled_vframe* v = vf->as_compiled(); lprintf(" <%#lx @ %#lx # %ld>", vf->fr, v->code, (void*)long(v->descOffset()->value())); } # endif methodMap *mm = (methodMap*) vf->method()->map(); stringOop file = mm->file(); if (file->length() > 0) { lprintf(" ("); file->string_print(); lprintf(":%ld): ", mm->line()->value()); } else { lprintf(" "); } # if defined(FAST_COMPILER) || defined(SIC_COMPILER) if (vf->is_compiled()) { compiled_vframe* v = vf->as_compiled(); if (v->desc->key.selector->is_string()) { stringOop(v->desc->key.selector)->string_print(); } else { v->desc->key.selector->print_oop(); } } # endif } else if (PrintOopAddress) { lprintf(" (%#lx) ", obj); } lprintf(">"); }
bool SCodeScope::shouldInlineSend(SendInfo* info, RScope* rs, SExpr* rcvr, oop m, InlineLimitType limitType) { MethodLookupKey* k = info->key; if (!k->selector->is_string()) return false; if (isRecursiveCall(m, k->receiverMapOop(), MaxRecursionUnroll)) { info->uninlinable = true; return false; } if (!Inline) { assert(InlineSTMessages, "shouldn't be here"); // NB: works only with rewritten whileTrue/False (using _Restart) if (isSmalltalkInlined(k->selector)) return true; if (isSmalltalkInlined(selector())) return true; return false; } if (limitType == NormalFnLimit) { // check args to see if any of them is a block; if so, increase limit fint top = exprStack->length(); fint argc = stringOop(k->selector)->arg_count(); for (fint i = argc; i > 0; i--) { if (exprStack->nth(top - i)->preg()->isBlockPReg()) { limitType = BlockArgFnLimit; goto done; } } // check receiver if (lookupReceiverIsSelf(k->lookupType)) { if (self->preg()->isBlockPReg()) limitType = BlockArgFnLimit; } else if (exprStack->nth(top - argc - 1)->preg()->isBlockPReg()) { limitType = BlockArgFnLimit; } } done: if (calleeTooBig(info, rs, limitType)) { // register this send as uninlinable theSIC->registerUninlinable(info, limitType, 9999); return false; } // NB: this test comes after calleeTooBig to prevent forced inlining of // e.g. a really complicated user-defined '+' for matrices if (isCheapMessage(stringOop(k->selector))) { msgCost = costP->cheapSendCost; return true; } fint cutoff = theSIC->inlineLimit[limitType]; msgCost = sicCost( m, this, costP); if (info->primFailure && info->nsends < MinPrimFailureInvocations) { if (rs->isPICScope() && ((RPICScope*)rs)->sd->isOptimized()) { // the fail block send is optimized, it's probably executed frequently } else if (rs->isSelfScope()) { // was inlined in previous version, so do it again } else { // don't inline error block unless trivial or taken often if (msgCost > MaxTrivialPrimFailureCost) return false; // should also look at block method, not default value:With: Map* map = rcvr->map(); if (map->is_block()) { slotsOop method = ((blockMap*)map)->value(); msgCost = sicCost( method, this, failCostP); // bug: should estimate real length of prim failure; e.g. could // have single send (cost 1) but that method sends more and more // msgs...i.e. need concept of "being in fail branch" so that // no further inlining takes place -- fix this if (msgCost > MaxTrivialPrimFailureCost) return false; } } } if (msgCost > cutoff) { if (calleeIsSmall(info, rs, limitType)) return true; theSIC->registerUninlinable(info, limitType, msgCost); return false; } return true; }