Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 151 lines (120 sloc) 2.974 kb
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
1 #include "vm.hpp"
2 #include "fiber_stack.hpp"
3 #include "fiber_data.hpp"
4
794333e Evan Phoenix Make stack pool and size configurable
evanphx authored
5 #include "configuration.hpp"
6
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
7 #include "bug.hpp"
8
ae50198 Evan Phoenix Move lowlevel Fiber marking to the Thread level
evanphx authored
9 #include "gc/gc.hpp"
10
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
11 #include <stdlib.h>
bb09356 Dirkjan Bussink Ensure that we tell Valgrind about our fiber stacks
dbussink authored
12 #ifdef HAVE_VALGRIND_H
13 #include <valgrind/valgrind.h>
14 #endif
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
15
16 namespace rubinius {
17
18 FiberStack::FiberStack(size_t size)
19 : address_(0)
20 , size_(size)
21 , refs_(0)
22 , user_(0)
23 {}
24
25 void FiberStack::allocate() {
26 assert(!address_);
27 address_ = malloc(size_);
bb09356 Dirkjan Bussink Ensure that we tell Valgrind about our fiber stacks
dbussink authored
28 #ifdef HAVE_VALGRIND_H
29 valgrind_id_ = VALGRIND_STACK_REGISTER(address_, (char *)address_ + size_);
30 #endif
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
31 }
32
33 void FiberStack::free() {
34 if(!address_) return;
bb09356 Dirkjan Bussink Ensure that we tell Valgrind about our fiber stacks
dbussink authored
35 #ifdef HAVE_VALGRIND_H
36 VALGRIND_STACK_DEREGISTER(valgrind_id_);
37 #endif
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
38 ::free(address_);
39 address_ = 0;
40 }
41
42 void FiberStack::flush(STATE) {
43 if(!user_) return;
44
45 // TODO assumes higher to lower stack growth.
46 user_->copy_to_heap(state);
47 }
48
49 void FiberStack::orphan(STATE, FiberData* user) {
75dce8b Evan Phoenix Work out the kinks in the fiber stack setup
evanphx authored
50 if(user == user_) {
51 user_ = 0;
52 }
53
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
54 dec_ref();
55 }
56
c690b3c Evan Phoenix Kill Fibers when their Thread dies
evanphx authored
57 FiberStacks::FiberStacks(VM* thread, SharedState& shared)
794333e Evan Phoenix Make stack pool and size configurable
evanphx authored
58 : max_stacks_(shared.config.fiber_stacks)
59 , stack_size_(shared.config.fiber_stack_size)
c690b3c Evan Phoenix Kill Fibers when their Thread dies
evanphx authored
60 , thread_(thread)
794333e Evan Phoenix Make stack pool and size configurable
evanphx authored
61 , trampoline_(0)
62 {}
63
c690b3c Evan Phoenix Kill Fibers when their Thread dies
evanphx authored
64 FiberStacks::~FiberStacks() {
65 for(Datas::iterator i = datas_.begin();
66 i != datas_.end();
67 ++i)
68 {
1d2e229 Dirkjan Bussink Revert "Plug memory leak in fibers"
dbussink authored
69 (*i)->die();
c690b3c Evan Phoenix Kill Fibers when their Thread dies
evanphx authored
70 }
71
72 for(Stacks::iterator i = stacks_.begin();
73 i != stacks_.end();
74 ++i)
75 {
76 i->free();
77 }
78 }
79
ae50198 Evan Phoenix Move lowlevel Fiber marking to the Thread level
evanphx authored
80 void FiberStacks::gc_scan(GarbageCollector* gc) {
81 for(Datas::iterator i = datas_.begin();
82 i != datas_.end();
83 ++i)
84 {
85 FiberData* data = *i;
86 if(data->dead_p()) continue;
87
88 AddressDisplacement dis(data->data_offset(),
89 data->data_lower_bound(),
90 data->data_upper_bound());
91
92 if(CallFrame* cf = data->call_frame()) {
93 gc->walk_call_frame(cf, &dis);
94 }
95
96 gc->scan(data->variable_root_buffers(), false, &dis);
97 }
98 }
99
c98174b Evan Phoenix Track the root fiber properly. Fixes #1568
evanphx authored
100 FiberData* FiberStacks::new_data(bool root) {
101 FiberData* data = new FiberData(thread_, root);
c690b3c Evan Phoenix Kill Fibers when their Thread dies
evanphx authored
102 datas_.push_back(data);
103
104 return data;
105 }
106
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
107 FiberStack* FiberStacks::allocate() {
108 for(Stacks::iterator i = stacks_.begin();
109 i != stacks_.end();
110 ++i)
111 {
112 if(i->unused_p()) {
113 i->inc_ref();
114 return &*i;
115 }
116 }
117
118 FiberStack* stack = 0;
119
794333e Evan Phoenix Make stack pool and size configurable
evanphx authored
120 if(stacks_.size() < max_stacks_) {
121 stacks_.push_back(FiberStack(stack_size_));
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
122 stack = &stacks_.back();
123
124 stack->allocate();
125 } else {
126 for(Stacks::iterator i = stacks_.begin();
127 i != stacks_.end();
128 ++i)
129 {
130 if(!stack || i->refs() < stack->refs()) {
131 stack = &*i;
132 }
133 }
134
135 assert(stack);
136 }
137
138 stack->inc_ref();
139
140 return stack;
141 }
75dce8b Evan Phoenix Work out the kinks in the fiber stack setup
evanphx authored
142
143 void* FiberStacks::trampoline() {
144 if(trampoline_ == 0) {
145 trampoline_ = malloc(cTrampolineSize);
146 }
147
148 return trampoline_;
149 }
e38045b Evan Phoenix Restructure how fiber stacks are allocated
evanphx authored
150 }
Something went wrong with that request. Please try again.