Fix FileSystem.cpp build on GCC.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn 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 * SourcePawn 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 * SourcePawn. 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"
31 #include "Environments.h"
32 #include "Structures.h"
39 // An ObjectVisitor is used for traversing object references in the heap. Since
40 // this pattern must be lightning fast, we avoid virtual dispatch by forcing
41 // visitors to compose themselves with the visiting logic.
43 class ObjectVisitor : public T
46 void visitField(Object *obj, size_t offset) {
47 this->visit(reinterpret_cast<Object **>(Address(obj) + offset));
50 size_t iterateType(Object *obj) {
51 visitField(obj, Type::offsetOfRoot());
55 size_t iterateEnumType(Object *obj) {
56 visitField(obj, EnumType::offsetOfName());
57 return sizeof(EnumType);
60 size_t iterateReferenceType(Object *obj) {
62 visitField(obj, ReferenceType::offsetOfContained());
63 return sizeof(ReferenceType);
66 size_t iterateArrayType(Object *obj) {
68 visitField(obj, ArrayType::offsetOfContained());
69 visitField(obj, ArrayType::offsetOfNewMap());
70 return sizeof(ArrayType);
73 size_t iterateStructType(Object *obj) {
75 visitField(obj, StructType::offsetOfFields());
76 visitField(obj, StructType::offsetOfNewMap());
77 visitField(obj, StructType::offsetOfName());
78 return sizeof(StructType);
81 size_t iterateFunctionType(Object *obj) {
83 visitField(obj, FunctionType::offsetOfReturnType());
84 visitField(obj, FunctionType::offsetOfParameters());
85 visitField(obj, FunctionType::offsetOfDefaults());
86 visitField(obj, FunctionType::offsetOfName());
87 return sizeof(FunctionType);
90 size_t iterateFixedArray(FixedArray *array) {
91 unsigned length = array->length();
92 Object **ptr = reinterpret_cast<Object **>(array + 1);
93 for (unsigned i = 0; i < length; i++)
95 return array->objSize();
98 size_t iterateByteArray(ByteArray *array) {
99 return array->objSize();
102 size_t iterateCode(Object *obj) {
103 visitField(obj, Code::offsetOfModule());
104 visitField(obj, Code::offsetOfBytecode());
105 visitField(obj, Code::offsetOfLocals());
106 visitField(obj, Code::offsetOfObjects());
107 visitField(obj, Code::offsetOfSafepoints());
108 visitField(obj, Code::offsetOfSourceMap());
109 visitField(obj, Code::offsetOfStrings());
113 size_t iterateReference(Object *obj) {
114 visitField(obj, Reference::offsetOfBase());
115 return sizeof(Reference);
118 void visitImportable(Object *obj) {
119 visitField(obj, Package::offsetOfName());
120 visitField(obj, Package::offsetOfParent());
121 visitField(obj, Package::offsetOfPath());
124 size_t iterateModule(Object *obj) {
125 visitImportable(obj);
126 visitField(obj, Module::offsetOfGlobals());
127 visitField(obj, Module::offsetOfCode());
128 return sizeof(Module);
131 size_t iteratePackage(Object *obj) {
132 visitImportable(obj);
133 visitField(obj, Package::offsetOfContents());
134 return sizeof(Package);
137 size_t iterateFunction(Object *obj) {
138 visitField(obj, Function::offsetOfCode());
139 visitField(obj, Function::offsetOfType());
140 visitField(obj, Function::offsetOfName());
141 return sizeof(Function);
144 size_t iterateDescriptor(Object *obj) {
145 visitField(obj, Descriptor::offsetOfName());
146 visitField(obj, Descriptor::offsetOfType());
147 return sizeof(Descriptor);
150 size_t iterateNative(Object *obj) {
151 visitField(obj, Native::offsetOfType());
152 return sizeof(Native);
155 size_t iterateString(Object *obj) {
156 return String::cast(obj)->objSize();
159 size_t iterateArray(Array *array, ArrayMap *map) {
160 if (!map->type()->hasInlineElements())
161 visitField(array, Array::offsetOfElements());
162 return array->objSize(map);
165 size_t iterateDependentArray(Object *array) {
166 visitField(array, DependentArray::offsetOfRoot());
167 return sizeof(DependentArray);
170 size_t iterateBox(Box *obj) {
171 visitField(obj, Box::offsetOfType());
172 if (obj->type()->isTraceable())
173 visitField(obj, Box::offsetOfObj());
177 size_t iterateArrayMap(ArrayMap *map) {
178 visitField(map, ArrayMap::offsetOfType());
179 return sizeof(ArrayMap);
182 size_t iterateEnvironmentSlotDescriptorArray(EnvironmentSlotDescriptorArray *env) {
183 unsigned length = env->length();
184 EnvironmentSlotDescriptor *desc = env->slots();
185 for (unsigned i = 0; i < length; i++)
186 this->visit(desc->type.addr());
187 return env->objSize();
190 size_t iterateEnvironmentMap(EnvironmentMap *map) {
191 visitField(map, EnvironmentMap::offsetOfSlots());
192 return map->objSize();
195 size_t iterateStructMap(StructMap *map) {
196 visitField(map, StructMap::offsetOfType());
197 visitField(map, StructMap::offsetOfComposed());
198 return map->objSize();
201 size_t iterateEnvironment(Environment *env) {
202 EnvironmentMap *map = env->map();
203 const unsigned *offsets = map->traceOffsets();
204 unsigned noffsets = map->traceOffsetCount();
205 for (unsigned i = 0; i < noffsets; i++)
206 visitField(env, Environment::offsetOfSlotOffset(offsets[i]));
207 return env->objSize();
210 size_t iterateStruct(Struct *obj) {
211 StructMap *map = obj->map();
212 const unsigned *offsets = map->traceOffsets();
213 unsigned noffsets = map->traceOffsetCount();
214 for (unsigned i = 0; i < noffsets; i++)
215 visitField(obj, Struct::offsetOfSlotOffset(offsets[i]));
216 return obj->objSize();
219 size_t iterateList(Object *obj) {
220 visitField(obj, List<Object>::offsetOfArray());
221 return sizeof(List<Object>);
225 size_t iterateObject(Object *obj) {
226 visitField(obj, Object::offsetOfMap());
227 return iterate(obj, obj->map());
230 size_t iterateObject(Object *obj, Map *map) {
231 switch (map->kind()) {
233 return iterateType(obj);
235 case MapKind_ReferenceType:
236 return iterateReferenceType(obj);
238 case MapKind_ArrayType:
239 return iterateArrayType(obj);
241 case MapKind_EnumType:
242 return iterateEnumType(obj);
244 case MapKind_FunctionType:
245 return iterateFunctionType(obj);
247 case MapKind_StructType:
248 return iterateStructType(obj);
250 case MapKind_FixedArray:
251 return iterateFixedArray(FixedArray::cast(obj));
253 case MapKind_ByteArray:
254 return iterateByteArray(ByteArray::cast(obj));
257 return iterateCode(obj);
259 case MapKind_Reference:
260 return iterateReference(obj);
263 return iterateModule(obj);
265 case MapKind_Package:
266 return iteratePackage(obj);
268 case MapKind_Function:
269 return iterateFunction(obj);
271 case MapKind_Descriptor:
272 return iterateDescriptor(obj);
275 return iterateString(obj);
278 return iterateArray(Array::cast(obj), ArrayMap::cast(map));
280 case MapKind_DependentArray:
281 return iterateDependentArray(obj);
284 return iterateBox(Box::cast(obj));
287 return iterateStruct(Struct::cast(obj));
290 return iterateList(obj);
292 case MapKind_EnvironmentSlotDescriptorArray:
293 return iterateEnvironmentSlotDescriptorArray(EnvironmentSlotDescriptorArray::cast(obj));
295 case MapKind_Environment:
296 return iterateEnvironment(Environment::cast(obj));
299 return iterateNative(obj);
301 case MapKind_MetaArray:
302 return iterateArrayMap(ArrayMap::cast(obj));
304 case MapKind_MetaEnvironment:
305 return iterateEnvironmentMap(EnvironmentMap::cast(obj));
307 case MapKind_MetaStruct:
308 return iterateStructMap(StructMap::cast(obj));
311 assert(map->kind() == MapKind_Meta);
317 size_t iterate(Object *obj) {
318 return Align(iterateObject(obj), kObjectAlignment);
321 size_t iterate(Object *obj, Map *map) {
322 return Align(iterateObject(obj, map), kObjectAlignment);
327 SizeOfObjectRaw(Object *obj, Map *map)
329 switch (map->kind()) {
333 case MapKind_ReferenceType:
334 return sizeof(ReferenceType);
336 case MapKind_ArrayType:
337 return sizeof(ArrayType);
339 case MapKind_EnumType:
340 return sizeof(EnumType);
342 case MapKind_FunctionType:
343 return sizeof(FunctionType);
345 case MapKind_StructType:
346 return sizeof(StructType);
348 case MapKind_FixedArray:
349 return FixedArray::cast(obj)->objSize();
351 case MapKind_ByteArray:
352 return ByteArray::cast(obj)->objSize();
357 case MapKind_Reference:
358 return sizeof(Reference);
361 return sizeof(Module);
363 case MapKind_Package:
364 return sizeof(Package);
366 case MapKind_Descriptor:
367 return sizeof(Descriptor);
369 case MapKind_Function:
370 return sizeof(Function);
373 return String::cast(obj)->objSize();
376 return sizeof(Native);
379 return Array::cast(obj)->objSize(ArrayMap::cast(map));
381 case MapKind_DependentArray:
382 return sizeof(DependentArray);
388 return sizeof(List<Object>);
391 return Struct::cast(obj)->objSize();
393 case MapKind_EnvironmentSlotDescriptorArray:
394 return EnvironmentSlotDescriptorArray::cast(obj)->objSize();
396 case MapKind_Environment:
397 return Environment::cast(obj)->objSize();
399 case MapKind_MetaArray:
400 return sizeof(ArrayMap);
402 case MapKind_MetaEnvironment:
403 return EnvironmentMap::cast(obj)->objSize();
405 case MapKind_MetaStruct:
406 return StructMap::cast(obj)->objSize();
408 case MapKind_FreeRegion:
409 return *reinterpret_cast<size_t *>(reinterpret_cast<Address>(obj + 1));
412 assert(map->kind() == MapKind_Meta);
418 SizeOfObject(Object *obj, Map *map)
420 return Align(SizeOfObjectRaw(obj, map), kObjectAlignment);
423 class ObjectSizeEvaluator
426 size_t operator()(Object *obj, Map *map) {
427 return SizeOfObject(obj, map);
433 #endif // _include_jc_object_visitor_h_