Skip to content

Commit e076e33

Browse files
committed
Lazily create ConstantTable storage.
1 parent f7d5e79 commit e076e33

File tree

3 files changed

+48
-19
lines changed

3 files changed

+48
-19
lines changed

kernel/bootstrap/constant_table.rb

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ def inspect
1111
end
1212
end
1313

14-
attr_reader :values
1514
attr_reader :bins
1615

1716
def size
@@ -67,9 +66,10 @@ def delete(name)
6766
def each
6867
raise LocalJumpError, "no block given" unless block_given?
6968

69+
vals = values
70+
7071
i = 0
7172
max = @bins
72-
vals = @values
7373

7474
while i < max
7575
if entry = vals.at(i)
@@ -83,6 +83,9 @@ def each
8383
self
8484
end
8585

86+
def values
87+
Rubinius.primitive :constant_table_values
88+
raise PrimitiveFailure, "ConstantTable#values primitive failed"
89+
end
8690
end
8791
end
88-

vm/builtin/constant_table.cpp

+37-14
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,21 @@ namespace rubinius {
2828
return tbl;
2929
}
3030

31-
void ConstantTable::setup(STATE, native_int sz = 0) {
32-
if(!sz) sz = CONSTANT_TABLE_MIN_SIZE;
33-
values(state, Tuple::create(state, sz));
34-
bins(state, Fixnum::from(sz));
31+
void ConstantTable::setup(STATE, native_int size) {
32+
if(size == 0) {
33+
values(state, nil<Tuple>());
34+
bins(state, Fixnum::from(0));
35+
} else {
36+
values(state, Tuple::create(state, size));
37+
bins(state, Fixnum::from(size));
38+
}
39+
3540
entries(state, Fixnum::from(0));
3641
}
3742

3843
/* The ConstantTable.allocate primitive. */
3944
ConstantTable* ConstantTable::allocate(STATE, Object* self) {
40-
ConstantTable* tbl = create(state, CONSTANT_TABLE_MIN_SIZE);
45+
ConstantTable* tbl = create(state);
4146
tbl->klass(state, as<Class>(self));
4247
tbl->lock_.init();
4348
return tbl;
@@ -55,7 +60,8 @@ namespace rubinius {
5560
native_int num = bins_->to_native();
5661

5762
for(native_int i = 0; i < num; i++) {
58-
ConstantTableBucket* entry = try_as<ConstantTableBucket>(values_->at(state, i));
63+
ConstantTableBucket* entry = try_as<ConstantTableBucket>(
64+
values(state)->at(state, i));
5965

6066
while(entry) {
6167
dup->store(state, entry->name(), entry->constant(), entry->visibility());
@@ -71,7 +77,8 @@ namespace rubinius {
7177
Tuple* new_values = Tuple::create(state, size);
7278

7379
for(native_int i = 0; i < num; i++) {
74-
ConstantTableBucket* entry = try_as<ConstantTableBucket>(values_->at(state, i));
80+
ConstantTableBucket* entry = try_as<ConstantTableBucket>(
81+
values(state)->at(state, i));
7582

7683
while(entry) {
7784
ConstantTableBucket* link = try_as<ConstantTableBucket>(entry->next());
@@ -94,21 +101,33 @@ namespace rubinius {
94101
bins(state, Fixnum::from(size));
95102
}
96103

104+
Tuple* ConstantTable::values(STATE) {
105+
if(values_->nil_p()) {
106+
values(state, Tuple::create(state, CONSTANT_TABLE_MIN_SIZE));
107+
bins(state, Fixnum::from(CONSTANT_TABLE_MIN_SIZE));
108+
}
109+
110+
return values_;
111+
}
112+
97113
Object* ConstantTable::store(STATE, Symbol* name, Object* constant, Symbol* vis) {
98114
check_frozen(state);
99115

100116
utilities::thread::SpinLock::LockGuard lg(lock_);
101117

118+
Tuple* values = this->values(state);
119+
102120
native_int num_entries = entries_->to_native();
103121
native_int num_bins = bins_->to_native();
104122

105123
if(max_density_p(num_entries, num_bins)) {
106124
redistribute(state, num_bins <<= 1);
125+
values = this->values(state);
107126
}
108127

109128
native_int bin = find_bin(key_hash(name), num_bins);
110129

111-
ConstantTableBucket* entry = try_as<ConstantTableBucket>(values_->at(state, bin));
130+
ConstantTableBucket* entry = try_as<ConstantTableBucket>(values->at(state, bin));
112131
ConstantTableBucket* last = NULL;
113132

114133
while(entry) {
@@ -129,8 +148,7 @@ namespace rubinius {
129148
if(last) {
130149
last->next(state, ConstantTableBucket::create(state, name, constant, vis));
131150
} else {
132-
values_->put(state, bin,
133-
ConstantTableBucket::create(state, name, constant, vis));
151+
values->put(state, bin, ConstantTableBucket::create(state, name, constant, vis));
134152
}
135153

136154
entries(state, Fixnum::from(num_entries + 1));
@@ -141,8 +159,11 @@ namespace rubinius {
141159
ConstantTableBucket* ConstantTable::find_entry(STATE, Symbol* name) {
142160
utilities::thread::SpinLock::LockGuard lg(lock_);
143161

162+
if(bins_->to_native() == 0) return 0;
163+
144164
native_int bin = find_bin(key_hash(name), bins_->to_native());
145-
ConstantTableBucket *entry = try_as<ConstantTableBucket>(values_->at(state, bin));
165+
ConstantTableBucket *entry = try_as<ConstantTableBucket>(
166+
values(state)->at(state, bin));
146167

147168
while(entry) {
148169
if(entry->name() == name) {
@@ -176,7 +197,8 @@ namespace rubinius {
176197
}
177198

178199
native_int bin = find_bin(key_hash(name), num_bins);
179-
ConstantTableBucket* entry = try_as<ConstantTableBucket>(values_->at(state, bin));
200+
ConstantTableBucket* entry = try_as<ConstantTableBucket>(
201+
values(state)->at(state, bin));
180202
ConstantTableBucket* last = NULL;
181203

182204
while(entry) {
@@ -185,7 +207,7 @@ namespace rubinius {
185207
if(last) {
186208
last->next(state, entry->next());
187209
} else {
188-
values_->put(state, bin, entry->next());
210+
values(state)->put(state, bin, entry->next());
189211
}
190212

191213
entries(state, Fixnum::from(entries_->to_native() - 1));
@@ -214,7 +236,8 @@ namespace rubinius {
214236
native_int num_bins = bins_->to_native();
215237

216238
for(native_int i = 0; i < num_bins; i++) {
217-
ConstantTableBucket* entry = try_as<ConstantTableBucket>(values_->at(state, i));
239+
ConstantTableBucket* entry = try_as<ConstantTableBucket>(
240+
values(state)->at(state, i));
218241

219242
while(entry) {
220243
ary->append(state, entry->name());

vm/builtin/constant_table.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ namespace rubinius {
6565

6666
/* interface */
6767

68-
static ConstantTable* create(STATE, native_int sz = CONSTANT_TABLE_MIN_SIZE);
69-
void setup(STATE, native_int sz);
68+
static ConstantTable* create(STATE, native_int size = 0);
69+
void setup(STATE, native_int size);
7070

7171
// Rubinius.primitive :constant_table_allocate
7272
static ConstantTable* allocate(STATE, Object* self);
@@ -77,6 +77,9 @@ namespace rubinius {
7777
// Rubinius.primitive :constant_table_duplicate
7878
ConstantTable* duplicate(STATE);
7979

80+
// Rubinius.primitive :constant_table_values
81+
Tuple* values(STATE);
82+
8083
ConstantTableBucket* find_entry(STATE, Symbol* name);
8184

8285
// Rubinius.primitive+ :constant_table_lookup

0 commit comments

Comments
 (0)