Add support for line and file information in backtraces.
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/.
19 #ifndef _include_jc_object_visitor_h_
20 #define _include_jc_object_visitor_h_
24 #include "FixedArray.h"
26 #include "Reference.h"
28 #include "Functions.h"
34 // An ObjectVisitor is used for traversing object references in the heap. Since
35 // this pattern must be lightning fast, we avoid virtual dispatch by forcing
36 // visitors to compose themselves with the visiting logic.
38 class ObjectVisitor : public T
41 void visitField(Object *obj, size_t offset) {
42 this->visit(reinterpret_cast<Object **>(Address(obj) + offset));
45 size_t iterateType(Object *obj) {
46 visitField(obj, Type::offsetOfContained());
47 visitField(obj, Type::offsetOfReturnType());
48 visitField(obj, Type::offsetOfParameters());
49 visitField(obj, Type::offsetOfTag());
53 size_t iterateFixedArray(FixedArray *array) {
54 unsigned length = array->length();
55 Object **ptr = reinterpret_cast<Object **>(array + 1);
56 for (unsigned i = 0; i < length; i++)
58 return FixedArray::SizeFor(length);
61 size_t iterateByteArray(ByteArray *array) {
62 return ByteArray::SizeFor(array->length());
65 size_t iterateCode(Object *obj) {
66 visitField(obj, Code::offsetOfModule());
67 visitField(obj, Code::offsetOfBytecode());
68 visitField(obj, Code::offsetOfLocals());
69 visitField(obj, Code::offsetOfObjects());
70 visitField(obj, Code::offsetOfSafepoints());
71 visitField(obj, Code::offsetOfSourceMap());
75 size_t iterateReference(Object *obj) {
76 visitField(obj, Reference::offsetOfBase());
77 return sizeof(Reference);
80 size_t iterateModule(Object *obj) {
81 visitField(obj, Module::offsetOfFunctions());
82 visitField(obj, Module::offsetOfPublics());
83 visitField(obj, Module::offsetOfNatives());
84 visitField(obj, Module::offsetOfFile());
85 return sizeof(Module);
88 size_t iterateFunction(Object *obj) {
89 visitField(obj, Function::offsetOfCode());
90 visitField(obj, Function::offsetOfType());
91 visitField(obj, Function::offsetOfName());
92 return sizeof(Function);
95 size_t iterateNative(Object *obj) {
96 visitField(obj, Native::offsetOfType());
97 visitField(obj, Native::offsetOfName());
98 return sizeof(Native);
101 size_t iterateString(Object *obj) {
102 return String::SizeFor(String::cast(obj)->length());
105 size_t iterateArray(Array *array, ArrayMap *map) {
106 if (map->type()->isArray()) {
107 unsigned length = array->nelements();
108 Object **vec = array->objVec();
109 for (unsigned i = 0; i < length; i++)
110 this->visit(vec + i);
112 return Array::SizeOf(array);
115 size_t iterateArrayMap(ArrayMap *map) {
116 visitField(map, ArrayMap::offsetOfType());
117 visitField(map, ArrayMap::offsetOfContained());
118 return sizeof(ArrayMap);
122 size_t iterate(Object *obj) {
123 visitField(obj, Object::offsetOfMap());
124 return iterate(obj, obj->map());
127 size_t iterate(Object *obj, Map *map) {
128 switch (map->kind()) {
130 return iterateType(obj);
132 case MapKind_FixedArray:
133 return iterateFixedArray(FixedArray::cast(obj));
135 case MapKind_ByteArray:
136 return iterateByteArray(ByteArray::cast(obj));
139 return iterateCode(obj);
141 case MapKind_Reference:
142 return iterateReference(obj);
145 return iterateModule(obj);
147 case MapKind_Function:
148 return iterateFunction(obj);
151 return iterateString(obj);
154 return Align(iterateArray(Array::cast(obj), ArrayMap::cast(map)), kObjectAlignment);
157 return iterateNative(obj);
159 case MapKind_MetaArray:
160 return iterateArrayMap(ArrayMap::cast(obj));
163 assert(map->kind() == MapKind_Meta);
170 SizeOfObject(Object *obj, Map *map)
172 switch (map->kind()) {
176 case MapKind_FixedArray:
177 return FixedArray::SizeFor(FixedArray::cast(obj)->length());
179 case MapKind_ByteArray:
180 return ByteArray::SizeFor(ByteArray::cast(obj)->length());
185 case MapKind_Reference:
186 return sizeof(Reference);
189 return sizeof(Module);
191 case MapKind_Function:
192 return sizeof(Function);
195 return String::SizeFor(String::cast(obj)->length());
198 return sizeof(Native);
201 return Align(Array::SizeOf(Array::cast(obj)), kObjectAlignment);
203 case MapKind_MetaArray:
204 return sizeof(ArrayMap);
206 case MapKind_FreeRegion:
207 return *reinterpret_cast<size_t *>(reinterpret_cast<Address>(obj + 1));
210 assert(map->kind() == MapKind_Meta);
215 class ObjectSizeEvaluator
218 size_t operator()(Object *obj, Map *map) {
219 return SizeOfObject(obj, map);
225 #endif // _include_jc_object_visitor_h_