return sizeof(callstack) + size;
}
-/* This is a little tricky. The iterator may allocate memory, so we
-keep the callstack in a GC root and use relative offsets */
-/* Allocates memory */
+// This is a little tricky. The iterator may allocate memory, so we
+// keep the callstack in a GC root and use relative offsets
+// Allocates memory
template <typename Iterator, typename Fixup>
inline void factor_vm::iterate_callstack_object(callstack* stack_,
Iterator& iterator,
Fixup& fixup) {
data_root<callstack> stack(stack_, this);
- fixnum frame_length = factor::untag_fixnum(stack->length);
+ fixnum frame_length = untag_fixnum(stack->length);
fixnum frame_offset = 0;
while (frame_offset < frame_length) {
- void* frame_top = stack->frame_top_at(frame_offset);
- void* addr = *(void**)frame_top;
+ cell frame_top = stack->frame_top_at(frame_offset);
+ cell addr = *(cell*)frame_top;
+ cell fixed_addr = Fixup::translated_code_block_map
+ ? (cell)fixup.translate_code((code_block*)addr)
+ : addr;
+ code_block* owner = code->code_block_for_address(fixed_addr);
- void* fixed_addr = Fixup::translated_code_block_map
- ? (void*)fixup.translate_code((code_block*)addr)
- : addr;
- code_block* owner = code->code_block_for_address((cell)fixed_addr);
- cell frame_size = owner->stack_frame_size_for_address((cell)fixed_addr);
+ cell frame_size = owner->stack_frame_size_for_address(fixed_addr);
iterator(frame_top, frame_size, owner, fixed_addr);
frame_offset += frame_size;
}
+ FACTOR_ASSERT(frame_offset == frame_length);
}
-/* Allocates memory */
+// Allocates memory
template <typename Iterator>
inline void factor_vm::iterate_callstack_object(callstack* stack,
Iterator& iterator) {
iterate_callstack_object(stack, iterator, none);
}
-/* Allocates memory */
+// Iterates the callstack from innermost to outermost
+// callframe. Allocates memory
template <typename Iterator, typename Fixup>
-inline void factor_vm::iterate_callstack(context* ctx, Iterator& iterator,
- Fixup& fixup) {
+void factor_vm::iterate_callstack(context* ctx, Iterator& iterator,
+ Fixup& fixup) {
- char* frame_top = (char*)ctx->callstack_top;
+ cell top = ctx->callstack_top;
+ cell bottom = ctx->callstack_bottom;
+ // When we are translating the code block maps, all callstacks must
+ // be empty.
+ FACTOR_ASSERT(!Fixup::translated_code_block_map || top == bottom);
- while (frame_top < (char*)ctx->callstack_bottom) {
- void* addr = *(void**)frame_top;
+ while (top < bottom) {
+ cell addr = *(cell*)top;
FACTOR_ASSERT(addr != 0);
- void* fixed_addr = Fixup::translated_code_block_map
- ? (void*)fixup.translate_code((code_block*)addr)
- : addr;
- code_block* owner = code->code_block_for_address((cell)fixed_addr);
- code_block* fixed_owner =
- Fixup::translated_code_block_map ? owner : fixup.translate_code(owner);
+ // Only the address is valid, if the code heap has been compacted,
+ // owner might not point to a real code block.
+ code_block* owner = code->code_block_for_address(addr);
+ code_block* fixed_owner = fixup.translate_code(owner);
- cell frame_size =
- fixed_owner->stack_frame_size_for_address((cell)fixed_addr);
+ cell delta = addr - (cell)owner - sizeof(code_block);
+ cell natural_frame_size = fixed_owner->stack_frame_size();
+ cell size = LEAF_FRAME_SIZE;
+ if (natural_frame_size > 0 && delta > 0)
+ size = natural_frame_size;
- void* fixed_addr_for_iter =
- Fixup::translated_code_block_map ? fixed_addr : addr;
-
- iterator(frame_top, frame_size, owner, fixed_addr_for_iter);
- frame_top += frame_size;
+ iterator(top, size, owner, addr);
+ top += size;
}
+ FACTOR_ASSERT(top == bottom);
}
-/* Allocates memory */
+// Allocates memory
template <typename Iterator>
inline void factor_vm::iterate_callstack(context* ctx, Iterator& iterator) {
no_fixup none;