]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/callstack.hpp
webapps.wiki: adding search bar
[factor.git] / vm / callstack.hpp
index f137701cb4fe93feae73d69b7fa6893b805379df..ebb19f268dce79e85040d1d7d390ce74f92fe119 100644 (file)
@@ -4,15 +4,15 @@ inline static cell callstack_object_size(cell size) {
   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) {
@@ -28,9 +28,10 @@ inline void factor_vm::iterate_callstack_object(callstack* stack_,
     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) {
@@ -38,35 +39,40 @@ inline void factor_vm::iterate_callstack_object(callstack* stack,
   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) {
 
-  cell frame_top = 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 < ctx->callstack_bottom) {
-    cell addr = *(cell*)frame_top;
+  while (top < bottom) {
+    cell addr = *(cell*)top;
     FACTOR_ASSERT(addr != 0);
-    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);
-    code_block* fixed_owner =
-        Fixup::translated_code_block_map ? owner : fixup.translate_code(owner);
 
-    cell frame_size = fixed_owner->stack_frame_size_for_address(fixed_addr);
+    // 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 fixed_addr_for_iter =
-        Fixup::translated_code_block_map ? fixed_addr : 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;
 
-    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;