00001
00002 #include "slate.hpp"
00003
00004
00005
00006
00007 void print_object(struct Object* oop) {
00008 if (oop == NULL) {
00009 printf("<object NULL>\n");
00010 return;
00011 }
00012 if (oop_is_smallint((word_t)oop)) {
00013 printf("<object int_value: %" PRIdPTR ">\n", object_to_smallint(oop));
00014 } else {
00015 const char* typestr=0;
00016 switch (object_type(oop)) {
00017 case TYPE_OBJECT: typestr = "normal"; break;
00018 case TYPE_OOP_ARRAY: typestr = "oop array"; break;
00019 case TYPE_BYTE_ARRAY: typestr = "byte array"; break;
00020 }
00021 printf("<object at %p, hash: 0x%" PRIxPTR ", size: %" PRIdPTR ", payload size: %" PRIdPTR ", type: %s>\n", (void*)oop, object_hash(oop), object_size(oop), payload_size(oop), typestr);
00022 }
00023
00024 }
00025
00026
00027 void print_symbol(struct Symbol* name) {
00028 if (fwrite(&name->elements[0], 1, payload_size((struct Object*)name), stdout) != (size_t)payload_size((struct Object*)name)) {
00029
00030 }
00031 }
00032
00033 void indent(word_t amount) { word_t i; for (i=0; i<amount; i++) printf(" "); }
00034
00035
00036 void print_byte_array(struct Object* o) {
00037 word_t i;
00038 char* elements = (char*)inc_ptr(o, object_array_offset(o));
00039 printf("'");
00040 for (i=0; i < payload_size(o); i++) {
00041 if (elements[i] >= 32 && elements[i] <= 126) {
00042 printf("%c", elements[i]);
00043 } else {
00044 printf("\\x%02" PRIxPTR "", (word_t)elements[i]);
00045 }
00046 if (i > 10 && payload_size(o) - i > 100) {
00047 i = payload_size(o) - 20;
00048 printf("{..snip..}");
00049 }
00050 }
00051 printf("'");
00052
00053 }
00054
00055
00056
00057 void print_object_with_depth(struct object_heap* oh, struct Object* o, word_t depth, word_t max_depth) {
00058
00059 struct Map* map;
00060 word_t i;
00061
00062 if (depth >= max_depth || object_is_smallint(o)) {
00063 printf("(depth limit reached) "); print_object(o);
00064 return;
00065 }
00066
00067 if (o == oh->cached.nil) {
00068 printf("<object NilObject>\n");
00069 return;
00070 }
00071
00072 map = o->map;
00073 print_object(o);
00074 if (object_hash(o) >= ID_HASH_RESERVED) {
00075 indent(depth); printf("<object is free/reserved>\n");
00076 return;
00077 }
00078
00079 indent(depth); printf("{\n");
00080
00081 if (object_type(o) == TYPE_BYTE_ARRAY) {
00082 indent(depth); printf("bytes: ");
00083 print_byte_array(o); printf("\n");
00084 }
00085 if (object_type(o) == TYPE_OOP_ARRAY) {
00086 struct OopArray* array = (struct OopArray*)o;
00087 indent(depth); printf("size(array) = %" PRIdPTR "\n", object_array_size(o));
00088 for (i=0; i < object_array_size(o); i++) {
00089 indent(depth); printf("array[%" PRIdPTR "]: ", i); print_object_with_depth(oh, array->elements[i], depth+1, max_depth);
00090 if (object_array_size(o) - i > 10) {
00091 indent(depth); printf("...\n");
00092 i = object_array_size(o) - 2;
00093 }
00094 }
00095 }
00096 indent(depth);
00097 printf("map flags: %" PRIdPTR " (%s)\n",
00098 object_to_smallint(map->flags),
00099 ((((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION)==0)? "delegation not restricted":"delegation restricted"));
00100
00101 {
00102
00103
00104 struct OopArray* delegates = map->delegates;
00105 word_t offset = object_array_offset((struct Object*)delegates);
00106 word_t limit = object_total_size((struct Object*)delegates);
00107 for (i = 0; offset != limit; offset += sizeof(word_t), i++) {
00108 struct Object* delegate = object_slot_value_at_offset((struct Object*)delegates, offset);
00109 indent(depth); printf("delegate[%" PRIdPTR "] = ", i);
00110 print_object_with_depth(oh, delegate,
00111 (((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION) == 0)? depth+1 : max(max_depth-1, depth+1), max_depth);
00112 }
00113 }
00114
00115 {
00116 struct SlotTable* slotTable = map->slotTable;
00117 word_t limit = slot_table_capacity(map->slotTable);
00118 indent(depth); printf("slot count: %" PRIdPTR "\n", object_to_smallint(map->slotCount));
00119 for (i=0; i < limit; i++) {
00120 if (slotTable->slots[i].name == (struct Symbol*)oh->cached.nil) continue;
00121 indent(depth);
00122 printf("slot[%" PRIdPTR "]['", i); print_symbol(slotTable->slots[i].name); printf("'] = ");
00123 {
00124 struct Object* obj = object_slot_value_at_offset(o, object_to_smallint(slotTable->slots[i].offset));
00125 if (object_is_smallint(obj) || object_type(obj) != TYPE_BYTE_ARRAY) {
00126 print_object(obj);
00127 } else {
00128 print_byte_array(obj); printf("\n");
00129 }
00130 }
00131 }
00132 }
00133
00134
00135
00136
00137
00138 {
00139 struct RoleTable* roleTable = map->roleTable;
00140 word_t limit = role_table_capacity(roleTable);
00141 indent(depth); printf("role table capacity: %" PRIdPTR "\n", limit);
00142 for (i = 0; i < limit; i++) {
00143 if (roleTable->roles[i].name == (struct Symbol*)oh->cached.nil) {continue;}
00144 else {
00145 indent(depth); printf("role[%" PRIdPTR "]['", i); print_symbol(roleTable->roles[i].name);
00146 printf("'] @ 0x%04" PRIxPTR "\n", object_to_smallint(roleTable->roles[i].rolePositions));
00147 #if 0
00148 print_object_with_depth(oh, (struct Object*)roleTable->roles[i].methodDefinition, max_depth, max_depth);
00149 #endif
00150 if (limit - i > 50 && depth >= 2) {
00151 indent(depth); printf("...\n");
00152 i = limit - 3;
00153 }
00154 }
00155
00156 }
00157
00158 }
00159
00160
00161 indent(depth); printf("}\n");
00162
00163 }
00164
00165 void print_detail(struct object_heap* oh, struct Object* o) {
00166 print_object_with_depth(oh, o, 1, 5);
00167 }
00168
00169 bool_t print_printname(struct object_heap* oh, struct Object* o) {
00170
00171 word_t i;
00172 struct Map* map = o->map;
00173 struct SlotTable* slotTable = map->slotTable;
00174 word_t limit = slot_table_capacity(slotTable);
00175 for (i=0; i < limit; i++) {
00176 if (slotTable->slots[i].name == (struct Symbol*)oh->cached.nil) continue;
00177 if (strncmp((char*)slotTable->slots[i].name->elements, "printName", 9) == 0) {
00178 struct Object* obj = object_slot_value_at_offset(o, object_to_smallint(slotTable->slots[i].offset));
00179 if (object_is_smallint(obj) || object_type(obj) != TYPE_BYTE_ARRAY) {
00180 return FALSE;
00181 } else {
00182 print_byte_array(obj);
00183 return TRUE;
00184 }
00185 }
00186 }
00187 return FALSE;
00188 }
00189
00190 void print_type(struct object_heap* oh, struct Object* o) {
00191 struct Object* traits;
00192 struct Object* traitsWindow;
00193 struct OopArray* x;
00194 if (object_is_smallint(o)) {
00195 printf("<smallint value: %" PRIdPTR " (0x%" PRIuPTR "x)>\n", object_to_smallint(o), object_to_smallint(o));
00196 return;
00197 }
00198
00199 if (object_type(o) == TYPE_BYTE_ARRAY) {
00200 printf("(");
00201 print_byte_array(o);
00202 printf(") ");
00203
00204 }
00205
00206 x = o->map->delegates;
00207 if (!x || array_size(x) < 1) goto fail;
00208
00209 traitsWindow = x->elements[0];
00210
00211 {
00212 if (traitsWindow == oh->cached.compiled_method_window) {
00213 printf("(method: ");
00214 print_byte_array((struct Object*)(((struct CompiledMethod*)o)->method->selector));
00215 printf(")");
00216 }
00217 }
00218
00219
00220 x = traitsWindow->map->delegates;
00221 if (!x || array_size(x) < 1) goto fail;
00222
00223 traits = x->elements[array_size(x)-1];
00224
00225
00226
00227 print_printname(oh, o);
00228
00229 printf("(");
00230 print_printname(oh, traits);
00231 printf(")\n");
00232
00233
00234 return;
00235 fail:
00236 printf("<unknown type>\n");
00237 }
00238
00239
00240 void print_stack(struct object_heap* oh) {
00241 struct Interpreter* i = oh->cached.interpreter;
00242 word_t size = i->stackPointer;
00243 word_t j;
00244 for (j=0; j < size; j++) {
00245 printf("stack[%" PRIdPTR "] = ", j);
00246 print_detail(oh, i->stack->elements[j]);
00247 }
00248 }
00249
00250 void print_stack_types(struct object_heap* oh, word_t last_count) {
00251 struct Interpreter* i = oh->cached.interpreter;
00252 word_t size = i->stackPointer;
00253 word_t j;
00254 for (j=0; j < size; j++) {
00255 if (size - j > last_count) continue;
00256 printf("stack[%" PRIdPTR "] = ", j);
00257 print_type(oh, i->stack->elements[j]);
00258 }
00259 }
00260
00261
00262 void print_backtrace(struct object_heap* oh) {
00263 word_t depth = 0, detail_depth = -1 ;
00264 struct Interpreter* i = oh->cached.interpreter;
00265 struct Closure* closure = (struct Closure*)i->method;
00266 word_t codePointer = i->codePointer;
00267 word_t fp = i->framePointer;
00268 word_t sp = i->stackPointer;
00269 word_t codeSize = i->codeSize;
00270 word_t resultStackPointer = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_RESULT_STACK_POINTER]);
00271 struct LexicalContext* lc = (struct LexicalContext*)i->stack->elements[fp - FRAME_OFFSET_LEXICAL_CONTEXT];;
00272 printf("printing backtrace from fp=%" PRIdPTR ", sp=%" PRIdPTR "\n", fp, i->stackPointer);
00273 do {
00274 word_t j;
00275 struct Object** vars;
00276 word_t input_count = object_to_smallint(closure->method->inputVariables);
00277 word_t local_count = object_to_smallint(closure->method->localVariables);
00278 vars = (closure->method->heapAllocate == oh->cached.true_object)? (&lc->variables[0]) : (&i->stack->elements[fp]);
00279 printf("------------------------------\n");
00280 printf("fp: %" PRIdPTR "\n", fp);
00281 printf("sp: %" PRIdPTR "\n", sp);
00282 printf("ip: %" PRIdPTR "/%" PRIdPTR "\n", codePointer, codeSize);
00283 printf("result: %" PRIdPTR "\n", resultStackPointer);
00284 printf("code: %p\n", closure->method->code);
00285 printf("selector: "); print_byte_array((struct Object*)(closure->method->selector)); printf("\n");
00286 printf("regs: %" PRIdPTR "\n", object_to_smallint(closure->method->registerCount));
00287 printf("heap alloc: %s\n", (closure->method->heapAllocate == oh->cached.true_object)? "true" : "false");
00288
00289 for (j = 0; j < input_count; j++) {
00290 printf("arg[%" PRIdPTR "] (%p) = ", j, (void*)vars[j]);
00291 if (depth > detail_depth) {
00292 print_type(oh, vars[j]);
00293 } else {
00294 print_detail(oh, vars[j]);
00295 }
00296 }
00297 if (closure->method->heapAllocate == oh->cached.true_object) {
00298 for (j = 0; j < local_count; j++) {
00299 printf("var[%" PRIdPTR "] (%p)= ", j, (void*)lc->variables[j]);
00300 if (depth > detail_depth) {
00301 print_type(oh, lc->variables[j]);
00302 } else {
00303 print_detail(oh, lc->variables[j]);
00304 }
00305 }
00306 } else {
00307 for (j = input_count; j < input_count + local_count; j++) {
00308 printf("var[%" PRIdPTR "] (%p) = ", j - input_count, (void*)vars[j]);
00309 if (depth > detail_depth) {
00310 print_type(oh, vars[j]);
00311 } else {
00312 print_detail(oh, vars[j]);
00313 }
00314 }
00315 }
00316
00317
00318
00319 codePointer = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_CODE_POINTER]);
00320 fp = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_PREVIOUS_FRAME_POINTER]);
00321 if (fp < FUNCTION_FRAME_SIZE) break;
00322 sp = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_BEFORE_CALL_STACK_POINTER]);
00323 resultStackPointer = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_RESULT_STACK_POINTER]);
00324 closure = (struct Closure*)i->stack->elements[fp - FRAME_OFFSET_METHOD];
00325 lc = (struct LexicalContext*)i->stack->elements[fp - FRAME_OFFSET_LEXICAL_CONTEXT];
00326 codeSize = array_size(closure->method->code);
00327 depth++;
00328 } while (fp >= FUNCTION_FRAME_SIZE);
00329
00330 }
00331
00332 void heap_print_objects(struct object_heap* oh, byte_t* memory, word_t memorySize) {
00333 struct Object* obj = (struct Object*) memory;
00334 word_t pin_count = 0, used_count = 0, free_count = 0;
00335 printf("\nmemory:\n");
00336 while (object_in_memory(oh, obj, memory, memorySize)) {
00337 if (object_is_pinned(oh, obj)) {
00338 printf("[pinned ");
00339 pin_count++;
00340 } else if (object_is_free(obj)) {
00341 printf("[free ");
00342 free_count++;
00343 } else {
00344 printf("[used ");
00345 used_count++;
00346 }
00347 printf("%" PRIdPTR "]\n", object_total_size(obj));
00348
00349 obj = object_after(oh, obj);
00350 }
00351 printf("\n");
00352 printf("free: %" PRIdPTR ", used: %" PRIdPTR ", pinned: %" PRIdPTR "\n", free_count, used_count, pin_count);
00353
00354 }
00355
00356
00357
00358 word_t heap_what_points_to_in(struct object_heap* oh, struct Object* x, byte_t* memory, word_t memorySize, bool_t print) {
00359 struct Object* obj = (struct Object*) memory;
00360 word_t count = 0;
00361 while (object_in_memory(oh, obj, memory, memorySize)) {
00362 word_t offset, limit;
00363 offset = object_first_slot_offset(obj);
00364 limit = object_last_oop_offset(obj) + sizeof(word_t);
00365 for (; offset != limit; offset += sizeof(word_t)) {
00366 struct Object* val = object_slot_value_at_offset(obj, offset);
00367 if (val == x) {
00368 if (!object_is_free(obj)) count++;
00369 if (print) print_object(obj);
00370 break;
00371 }
00372 }
00373 obj = object_after(oh, obj);
00374 }
00375 return count;
00376
00377 }
00378
00379 word_t heap_what_points_to(struct object_heap* oh, struct Object* x, bool_t print) {
00380
00381 return heap_what_points_to_in(oh, x, oh->memoryOld, oh->memoryOldSize, print) + heap_what_points_to_in(oh, x, oh->memoryYoung, oh->memoryYoungSize, print);
00382
00383 }
00384
00385
00386 void heap_print_marks(struct object_heap* oh, byte_t* memory, word_t memorySize) {
00387 struct Object* obj = (struct Object*) memory;
00388 word_t count = 80;
00389 word_t pin_count = 0, used_count = 0, free_count = 0;
00390 printf("\nmemory:\n");
00391 while (object_in_memory(oh, obj, memory, memorySize)) {
00392 if (object_is_pinned(oh, obj)) {
00393 printf("X");
00394 pin_count++;
00395 } else if (object_is_free(obj)) {
00396 printf(" ");
00397 free_count++;
00398 } else {
00399 printf("*");
00400 used_count++;
00401 }
00402 count--;
00403 if (count == 0) {
00404 count = 80;
00405 printf("\n");
00406 }
00407
00408 obj = object_after(oh, obj);
00409 }
00410 printf("\n");
00411 printf("free: %" PRIdPTR ", used: %" PRIdPTR ", pinned: %" PRIdPTR "\n", free_count, used_count, pin_count);
00412
00413 }
00414
00415
00416 void print_pic_entries(struct object_heap* oh, struct CompiledMethod* method) {
00417 if ((struct Object*)method->calleeCount == oh->cached.nil) return;
00418
00419 for (word_t i = 0; i < array_size(method->calleeCount); i += CALLER_PIC_ENTRY_SIZE) {
00420 struct MethodDefinition* def = (struct MethodDefinition*)method->calleeCount->elements[i+PIC_CALLEE];
00421 if ((struct Object*)def == oh->cached.nil) continue;
00422 struct CompiledMethod* picMethod = (struct CompiledMethod*)def->method;
00423 struct Object* traitsWindow = picMethod->base.map->delegates->elements[0];
00424 assert (traitsWindow == oh->cached.compiled_method_window || traitsWindow == oh->cached.primitive_method_window);
00425 struct Symbol* picSelector = picMethod->selector;
00426 print_type(oh, (struct Object*)picSelector);
00427 }
00428
00429 }
00430
00431
00432
00433 void print_code_disassembled(struct object_heap* oh, struct OopArray* slatecode) {
00434 std::vector<struct Object*> code;
00435 optimizer_append_code_to_vector(slatecode, code);
00436 print_code(oh, code);
00437 }
00438