1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
26 #include "CompactBuffer.h"
27 #include "Structures.h"
33 OpInfo ke::OpcodeInfo[] =
35 #define OPDEF(name, text, length, uses, defs) \
36 {text, length, uses, defs},
37 #include "Opcodes.tbl"
42 Code::New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
43 Handle<FixedArray> objects, Handle<FixedArray> strings, unsigned maxStackDepth,
44 unsigned maxLoopDepth, Handle<ByteArray> safepoints, Handle<ByteArray> sourcemap)
46 Local<Code> code(zone, Code::cast(zone->allocate(MapKind_Code, sizeof(Code), Heap::Tenure_Old)));
50 code->bytecode_ = bytecode;
51 code->locals_ = locals;
52 code->objects_ = objects;
53 code->maxStackDepth_ = maxStackDepth;
55 code->safepoints_ = safepoints;
56 code->sourcemap_ = sourcemap;
57 code->lineNumber_ = 0;
58 code->strings_ = strings;
59 code->maxLoopDepth_ = maxLoopDepth;
64 CompareSafepoints(const void *a, const void *b)
66 const unsigned *sa = reinterpret_cast<const unsigned *>(a);
67 const unsigned *sb = reinterpret_cast<const unsigned *>(b);
76 Code::safepointAt(unsigned pcOffset)
78 // Only specific opcodes may have safepoints. Asking for a safepoint at
79 // any other position indicates a failure to mark that position as a
80 // safepoint, which is a bug.
82 Opcode op = Opcode(*(start() + pcOffset));
83 assert(op == OP_CALL ||
87 op == OP_VARREF_LIFO ||
88 op == OP_ARGREF_LIFO ||
89 op == OP_SLOTREF_LIFO ||
91 op == OP_CALLNATIVE ||
98 size_t bytesPerSafepoint = BytesPerSafepoint(maxStackDepth());
99 assert(!(safepoints_->length() % bytesPerSafepoint));
101 size_t count = safepoints_->length() / bytesPerSafepoint;
103 void *result = bsearch(&pcOffset,
112 assert(*reinterpret_cast<unsigned *>(result) == pcOffset);
114 return Address(result) + sizeof(unsigned);
118 Code::pcToSource(unsigned pc)
120 assert(pc < bytecode_->length());
122 CompactBufferReader reader(sourcemap_->raw(), sourcemap_->raw() + sourcemap_->length());
127 while (!reader.done()) {
128 curPc += reader.readUint32();
132 line = reader.readUint32();
133 col = reader.readUint32();
136 return SourcePosition(lineNumber_ + line, col);
139 // All jumps must be the same length.
140 STATIC_ASSERT(OP_JT_LENGTH == OP_JUMP_LENGTH);
141 STATIC_ASSERT(OP_JF_LENGTH == OP_JUMP_LENGTH);
144 ke::Disassemble(Code *code, FILE *fp)
146 bytecode *pc = code->start();
148 Opcode op = Opcode(*pc);
150 fprintf(fp, "%-4d %s ", int(pc - code->start()), OpcodeInfo[op].name);
179 case OP_SLOTREF_LIFO:
219 fprintf(fp, "; lifo region");
227 fprintf(fp, "%d", READ_INT32(pc));
231 fprintf(fp, "%f", READ_FLOAT(pc));
239 fprintf(fp, "%u (%+d)", unsigned((pc + READ_INT32(pc)) - code->start()), READ_INT32(pc));
246 Heap::Tenure tenure = (Heap::Tenure)pc[1];
247 //ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc + 1)));
248 if (tenure == Heap::Tenure_Stack)
249 fprintf(fp, " ; lifo");
250 else if (tenure == Heap::Tenure_Old)
251 fprintf(fp, " ; pretenured");
252 else if (tenure == Heap::Tenure_Default)
253 fprintf(fp, " ; newborn");
259 Heap::Tenure tenure = (Heap::Tenure)pc[1];
260 StructMap *map = StructMap::cast(code->map(READ_UINT32(pc + 1)));
261 fprintf(fp, "%s", StructType::cast(map->type())->name()->chars());
262 if (tenure == Heap::Tenure_Stack)
263 fprintf(fp, " ; lifo");
264 else if (tenure == Heap::Tenure_Old)
265 fprintf(fp, " ; pretenured");
266 else if (tenure == Heap::Tenure_Default)
267 fprintf(fp, " ; newborn");
282 fprintf(fp, "%u", READ_UINT32(pc));
287 unsigned argc = READ_UINT32(pc);
288 fprintf(fp, " ; %u args", argc);
294 int low = READ_TABLESWITCH_LOW(pc);
295 int high = READ_TABLESWITCH_HIGH(pc);
296 fprintf(fp, "%d, %d\n", low, high);
303 unsigned index = READ_UINT32(pc);
304 fprintf(fp, "%s", String::cast(code->strings()->at(index))->chars());
310 unsigned index = READ_UINT32(pc);
311 FixedArray *path = code->module()->importPathAt(index);
313 for (unsigned i = 0; i < path->length(); i++) {
314 fprintf(fp, "%s", String::cast(path->at(i))->chars());
315 if (i != path->length() - 1)
331 pc += OpcodeInfo[op].length;
332 assert(pc < code->start() + code->length());
335 fprintf(fp, "\nSafepoints:\n");
336 ByteArray *safepoints = code->safepoints();
338 size_t nsafepoints = safepoints->length() / Code::BytesPerSafepoint(code->maxStackDepth());
339 for (size_t i = 0; i < nsafepoints; i++) {
340 Address address = safepoints->raw() + Code::BytesPerSafepoint(code->maxStackDepth()) * i;
341 fprintf(fp, "%4d: ", *reinterpret_cast<unsigned *>(address));
342 unsigned char *bits = (unsigned char *)(address + sizeof(unsigned));
343 for (unsigned j = 0; j < code->maxStackDepth(); j++) {
344 if (bits[j / 8] & (1 << (j % 8)))
345 fprintf(fp, "%d ", j);