void itable_interface_at_put(int index, int class_id) { #ifdef AZZERT Oop cls = Universe::class_from_id(class_id); GUARANTEE(!cls.is_null(), "sanity"); #endif int_field_put(itable_offset_from_index(index), class_id); }
void ppxv(int x) { bool oldVerbose = Verbose; Verbose = true; Oop o = (OopDesc*)x; o.print(); Verbose = oldVerbose; }
void CompiledMethod::print_code_on(Stream* st) { int end_offset = RelocationReader::code_length(this); for (int offset = 0; offset < end_offset; offset += 2) { short* instruction_start = (short*) (entry() + offset); print_comment_for(offset, st); bool is_oop = false; for (RelocationReader stream(this); !stream.at_end(); stream.advance()) { if (stream.code_offset() == offset) { if (stream.is_oop() || stream.is_rom_oop()) { is_oop = true; break; } } } st->print(" %4d: ", offset); if (VerbosePointers) { st->print("0x%08x: ", instruction_start); } if (!is_oop) { decode_instruction(st, instruction_start, offset); } else { GUARANTEE(((int)instruction_start & 0x3) == 0, "Disassembler: Invalid embedded Oop"); Oop o = (OopDesc*)*(int*)instruction_start; if (VerbosePointers) { st->print("0x%08x:", *(int*)instruction_start); } o.print_value_on(st); offset += 2; } st->cr(); } }
/** Inspired by: !Interpreter methodsFor: 'image save/restore' stamp: 'dtl 10/5/2010 23:54'! normalizeFloatOrderingInImage "Float objects were saved in platform word ordering. Reorder them into the traditional object format." */ void Squeak_Image_Reader::normalize_float_ordering_in_image() { Squeak_Interpreter* const interp = The_Squeak_Interpreter(); Memory_System* const mem_sys = The_Memory_System(); Oop cls = interp->splObj(Special_Indices::ClassFloat); for (Oop floatInstance = mem_sys->initialInstanceOf(cls); floatInstance != interp->roots.nilObj; floatInstance = mem_sys->nextInstanceAfter(floatInstance) ) { /* Swap words within Float objects, taking them out of native platform ordering */ floatInstance.as_object()->swapFloatParts_for_cog_compatibility(); } }
void find(int x) { OopDesc** p = (OopDesc**) x; if (ObjectHeap::contains_live(p)) { Oop o = ObjectHeap::slow_object_start(p); tty->print_cr("0x%p in object 0x%p", x, o.obj()); o.print(); } else if (ObjectHeap::contains(p)) { tty->print_cr("0x%p inside dead region of ObjectHeap", x); } else { tty->print_cr("0x%p unknown location", x); } }
// Print this EntryActivation and all other EntryActivation's that follow it. void EntryActivation::print_list_on(Stream* st, int indent, int index) { #if USE_DEBUG_PRINTING int last_indent = st->indentation(); st->set_indentation(indent); st->indent(); st->print("[%d] ", index); Method m = method(); m.print_value_on(st); st->cr(); for (int i = 0; i < length(); i++) { st->indent(); st->print(" "); switch(tag_at(i)) { case float_tag: st->print("(float) %f", jvm_f2d(float_at(i))); break; case double_tag: st->print("(double) %d", double_at(i)); i++; break; case long_tag: st->print("(long) "); st->print(OsMisc_jlong_format_specifier(), long_at(i)); i++; break; case obj_tag: { st->print("(obj) "); Oop obj = obj_at(i); obj.print_value_on(st); } break; case int_tag: st->print("(int) %d", int_at(i)); break; default: SHOULD_NOT_REACH_HERE(); } st->cr(); } EntryActivation mynext = next(); if (mynext.not_null()) { mynext.print_list_on(st, indent, index+1); } st->set_indentation(last_indent); #endif }
void Execution_Tracer::check_it(Oop ents) { Object_p eo = ents.as_object(); int wl = eo->fetchWordLength(); int n = wl / e_N; for (int i = 0; i < n; ++i) { int x = -1; Oop rank = eo->fetchPointer(x = i * e_N + e_rank); assert_always( rank.is_int()); switch (eo->fetchPointer(i * e_N + e_kind).integerValue()) { default: fatal(); case k_bc: { Oop meth = eo->fetchPointer(x = i * e_N + e_method); assert_always(meth.is_mem()); Oop rcvr = eo->fetchPointer(x = i * e_N + e_rcvr); Oop pc = eo->fetchPointer(x = i * e_N + e_pc ); assert_always(pc.is_int()); Oop is_block = eo->fetchPointer(x = i * e_N + e_is_block); assert_always(is_block == The_Squeak_Interpreter()->roots.trueObj || is_block == The_Squeak_Interpreter()->roots.falseObj); break; } case k_gc: { Oop gc = eo->fetchPointer(x = i * e_N + e_gc ); assert_always(gc.is_int()); } break; case k_proc: { Oop process = eo->fetchPointer(x = i * e_N + e_process); assert_always(process.is_mem()); } break; case k_rcved_interp: break; case k_aux: break; } } }
void LinkedBasicOop::pre_push_handle_verification() { // Check this and top handle are not in object heap GUARANTEE(BasicOop::on_stack_check_disabled() || !ObjectHeap::contains((OopDesc*) _last_handle), "handle should be on stack"); GUARANTEE(BasicOop::on_stack_check_disabled() || !ObjectHeap::contains((OopDesc*) this), "handle should be on stack"); #ifdef NOTCURRENTLYUSED GUARANTEE(!ObjectHeap::is_gc_active(), "shouldn't create handles during GC"); #endif // Make sure that there loops in the handle stack. // This could happen from bad usage of ::Fast. Oop* handle = _last_handle; for (int i = 0; handle != NULL && i < 5; handle = handle->previous(), i++) { GUARANTEE((address)handle != (address)this, "Loop in handles"); } }
void GarbageCollector::markObject(Oop objectPointer) { // TODO: Use the schorr-waite algorithm. // mark pointer objects. if(!objectPointer.isPointer()) return; // Get the object header. auto header = objectPointer.header; if(header->gcColor) return; // Mark gray header->gcColor = Gray; // Mark recursively the children auto format = header->objectFormat; if(format == OF_FIXED_SIZE || format == OF_VARIABLE_SIZE_NO_IVARS || format == OF_VARIABLE_SIZE_IVARS) { auto slotCount = header->slotCount; auto headerSize = sizeof(ObjectHeader); if(slotCount == 255) slotCount = reinterpret_cast<uint64_t*> (header)[-1]; // Traverse the slots. auto slots = reinterpret_cast<Oop*> (objectPointer.pointer + headerSize); for(size_t i = 0; i < slotCount; ++i) markObject(slots[i]); } // Special handilng of compiled method literals if(format >= OF_COMPILED_METHOD) { auto compiledMethod = reinterpret_cast<CompiledMethod*> (objectPointer.pointer); auto literalCount = compiledMethod->getLiteralCount(); auto literals = compiledMethod->getFirstLiteralPointer(); for(size_t i = 0; i < literalCount; ++i) markObject(literals[i]); } // Mark as black before ending. header->gcColor = Black; }
void Profiling_Tracer::record_for_profile(Oop meth, Oop rcvr, bool is_block) { if (Logical_Core::num_cores > 1) return; static std::string lastSignature; std::map<std::string, int>* profile; #warning Stefan: warning, not threadsafe get_profile(&profile); static char buff[2024]; StringPrinter p(buff, 2023); Oop klass = rcvr.fetchClass(); Oop sel, mclass; bool have_sel_and_mclass = klass.as_object()->selector_and_class_of_method_in_me_or_ancestors(meth, &sel, &mclass); if (!have_sel_and_mclass) return; if (mclass == The_Squeak_Interpreter()->roots.nilObj) mclass = rcvr.fetchClass(); rcvr.print(&p); if (mclass != klass) { p.printf("("); bool is_meta; Oop mclassName = mclass.as_object()->name_of_class_or_metaclass(&is_meta); if (is_meta) p.printf("class "); mclassName.as_object()->print_bytes(&p); p.printf(")"); } p.printf(">>"); sel.as_object()->print_bytes(&p); if (is_block) p.printf("[]"); buff[2023] = 0; std::string signature(buff); if (lastSignature != signature) { lastSignature = signature; ++(*profile)[lastSignature]; } // STEFAN: a little hack to be able to get the printout during debugging, any better ways to do so? static bool print_profile = false; if (print_profile) { this->print_profile(debug_printer); } }
Oop Squeak_Image_Reader::oop_for_oop(Oop x) { return oop_for_relative_addr(x.bits() - (int)oldBaseAddr); }
bool has_comment() { return !_oop.is_null() || _comment != NULL; }
void dp(Oop x) {x.dp();} // debugging
bool Oop::isKindOf(char* className) { for (Oop klass = fetchClass(); klass != The_Squeak_Interpreter()->roots.nilObj; klass = klass.as_object()->superclass()) if (klass.as_object()->className().as_object()->equals_string(className)) return true; return false; }
// Oop bufferOop, Oop offsetOop, Oop sizeOop, Oop fileOop int OSIO::stWriteOffsetSizeTo(InterpreterProxy *interpreter) { if(interpreter->getArgumentCount() != 4) return interpreter->primitiveFailed(); Oop bufferOop = interpreter->getTemporary(0); Oop offsetOop = interpreter->getTemporary(1); Oop sizeOop = interpreter->getTemporary(2); Oop fileOop = interpreter->getTemporary(3); // Check the arguments. if(!bufferOop.isIndexableNativeData() || !offsetOop.isSmallInteger() || !sizeOop.isSmallInteger() || !fileOop.isSmallInteger()) return interpreter->primitiveFailed(); // Decode the arguments auto buffer = reinterpret_cast<uint8_t *> (bufferOop.getFirstFieldPointer()); auto offset = offsetOop.decodeSmallInteger(); auto size = sizeOop.decodeSmallInteger(); auto file = fileOop.decodeSmallInteger(); // Validate some of the arguments. if(offset < 0) return interpreter->primitiveFailed(); // Perform the write auto res = write(file, buffer + offset, size); return interpreter->returnSmallInteger(res); }
void ppx(int x) { Oop o = (OopDesc*)x; o.print(); }
sqInt fetchPointerofObject(sqInt x, sqInt y) { Oop r = Oop::from_bits(y).as_object()->fetchPointer(x); if (check_many_assertions) r.verify_oop(); return r.bits(); }
void Execution_Tracer::print_entries(Oop ents, Printer* p) { Object_p eo = ents.as_object(); int n = eo->fetchWordLength() / e_N; int x; for (int i = 0; i < n; ++i) { int rank = eo->fetchPointer(x = i * e_N + e_rank).integerValue(); p->printf("%3d on %2d: ", i - n, rank); switch (eo->fetchPointer(i * e_N + e_kind).integerValue()) { default: fatal(); break; case k_proc: { Oop process = eo->fetchPointer(i * e_N + e_process); assert(process.is_mem()); p->printf("switch to process 0x%x", process.as_untracked_object_ptr()); } break; case k_aux: { int rank = eo->fetchPointer(i * e_N + e_rank).integerValue(); int aux1 = eo->fetchPointer(i * e_N + e_aux1).integerValue(); //int aux2 = eo->fetchPointer(i * e_N + e_aux2).integerValue(); int id = eo->fetchPointer(i * e_N + e_id ).integerValue(); // p->printf("on %d: aux1 0x%x aux2 0x%x id %d", rank, aux1, aux2, id); p->printf("on %d: aux1 %s id %d", rank, aux1, id); } break; case k_gc: p->printf("gc: %d", eo->fetchPointer(i * e_N + e_gc).integerValue()); break; case k_rcved_interp: p->printf("received interp"); break; case k_bc: { Oop meth = eo->fetchPointer(i * e_N + e_method); assert(meth.is_mem()); Oop rcvr = eo->fetchPointer(i * e_N + e_rcvr); int pc = eo->fetchPointer(i * e_N + e_pc ).integerValue(); bool is_block = eo->fetchPointer(i * e_N + e_is_block) == The_Squeak_Interpreter()->roots.trueObj; int aux1 = eo->fetchPointer(i * e_N + e_aux1).integerValue(); int aux2 = eo->fetchPointer(i * e_N + e_aux2).integerValue(); Oop klass = rcvr.fetchClass(); Oop sel, mclass; bool have_sel_and_mclass = klass.as_object()->selector_and_class_of_method_in_me_or_ancestors(meth, &sel, &mclass); if (!have_sel_and_mclass) continue; if (mclass == The_Squeak_Interpreter()->roots.nilObj) mclass = rcvr.fetchClass(); p->printf("rcvr: "); rcvr.print(p); if (mclass != klass) { p->printf("("); bool is_meta; Oop mclassName = mclass.as_object()->name_of_class_or_metaclass(&is_meta); if (is_meta) p->printf("class "); mclassName.as_object()->print_bytes(p); p->printf(")"); } p->printf(" >> "); sel.as_object()->print_bytes(p); p->printf(is_block ? " [] " : " "); p->printf(", pc: %d, ", pc); Object_p mo = meth.as_object(); u_char bc = mo->first_byte_address()[pc]; The_Squeak_Interpreter()->printBC(bc, p); p->printf(", bcCount %d", eo->fetchPointer(i * e_N + e_bcCount).integerValue()); if (aux1) p->printf(", aux1 = 0x%x", aux1); if (aux1) p->printf(", aux1 = 0x%x", aux2); } break; } p->nl(); } }