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/.
30 OpInfo ke::OpcodeInfo[] =
32 #define OPDEF(name, number, text, length, uses, defs) \
33 {text, length, uses, defs},
34 #include "Opcodes.tbl"
39 Code::New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
40 Handle<FixedArray> objects, unsigned maxStackDepth, Handle<Module> module,
41 Handle<ByteArray> safepoints)
43 Local<Code> code(zone, Code::cast(zone->allocate(MapKind_Code, sizeof(Code), Heap::Tenure_Old)));
47 code->bytecode_ = bytecode;
48 code->locals_ = locals;
49 code->objects_ = objects;
50 code->maxStackDepth_ = maxStackDepth;
51 code->module_ = module;
52 code->safepoints_ = safepoints;
57 CompareSafepoints(const void *a, const void *b)
59 const unsigned *sa = reinterpret_cast<const unsigned *>(a);
60 const unsigned *sb = reinterpret_cast<const unsigned *>(b);
69 Code::safepointAt(unsigned pcOffset)
71 // Only specific opcodes may have safepoints. Asking for a safepoint at
72 // any other position indicates a failure to mark that position as a
73 // safepoint, which is a bug.
74 Opcode op = Opcode(*(start() + pcOffset));
75 assert(op == OP_CALLGLOBAL || op == OP_NEWARRAY_LIFO || op == OP_VARREF_LIFO ||
76 op == OP_ARGREF_LIFO || op == OP_SLOTREF_LIFO || op == OP_ARRAYREF_LIFO ||
82 size_t bytesPerSafepoint = BytesPerSafepoint(maxStackDepth());
83 assert(!(safepoints_->length() % bytesPerSafepoint));
85 size_t count = safepoints_->length() / bytesPerSafepoint;
87 void *result = bsearch(&pcOffset,
96 assert(*reinterpret_cast<unsigned *>(result) == pcOffset);
98 return Address(result) + sizeof(unsigned);
101 // All jumps must be the same length.
102 STATIC_ASSERT(OP_JL_LENGTH == OP_JUMP_LENGTH);
103 STATIC_ASSERT(OP_JLE_LENGTH == OP_JUMP_LENGTH);
104 STATIC_ASSERT(OP_JG_LENGTH == OP_JUMP_LENGTH);
105 STATIC_ASSERT(OP_JGE_LENGTH == OP_JUMP_LENGTH);
106 STATIC_ASSERT(OP_JEQ_LENGTH == OP_JUMP_LENGTH);
107 STATIC_ASSERT(OP_JNE_LENGTH == OP_JUMP_LENGTH);
108 STATIC_ASSERT(OP_JT_LENGTH == OP_JUMP_LENGTH);
109 STATIC_ASSERT(OP_JF_LENGTH == OP_JUMP_LENGTH);
112 ke::Disassemble(Code *code, FILE *fp)
114 bytecode *pc = code->start();
116 Opcode op = Opcode(*pc);
118 fprintf(fp, "%-4d %s ", int(pc - code->start()), OpcodeInfo[op].name);
151 case OP_SLOTREF_LIFO:
152 case OP_ARRAYREF_LIFO:
168 fprintf(fp, "%d", READ_INT32(pc));
172 fprintf(fp, "%f", READ_FLOAT(pc));
184 fprintf(fp, "%u (%+d)", unsigned((pc + READ_INT32(pc)) - code->start()), READ_INT32(pc));
187 case OP_NEWARRAY_LIFO:
189 ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc)));
190 fprintf(fp, "%s:", map->type()->innermost()->tag()
191 ? map->type()->innermost()->tag()->chars()
193 for (; map; map = map->contained()) {
194 Type *type = map->type();
195 fprintf(fp, "[%d]", type->elements());
209 fprintf(fp, "%u", READ_UINT32(pc));
222 pc += OpcodeInfo[op].length;
223 assert(pc < code->start() + code->length());
226 fprintf(fp, "\nSafepoints:\n");
227 ByteArray *safepoints = code->safepoints();
229 size_t nsafepoints = safepoints->length() / Code::BytesPerSafepoint(code->maxStackDepth());
230 for (size_t i = 0; i < nsafepoints; i++) {
231 Address address = safepoints->raw() + Code::BytesPerSafepoint(code->maxStackDepth()) * i;
232 fprintf(fp, "%4d: ", *reinterpret_cast<unsigned *>(address));
233 unsigned char *bits = (unsigned char *)(address + sizeof(unsigned));
234 for (unsigned j = 0; j < code->maxStackDepth(); j++) {
235 if (bits[j / 8] & (1 << (j % 8)))
236 fprintf(fp, "%d ", j);