Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: src/compilation-cache.cc

Issue 140056: Add generations to the compilation cache for eval and regexp (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compilation-cache.h ('k') | src/compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 14 matching lines...) Expand all
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "compilation-cache.h" 30 #include "compilation-cache.h"
31 31
32 namespace v8 { 32 namespace v8 {
33 namespace internal { 33 namespace internal {
34 34
35 enum {
36 // The number of script generations tell how many GCs a script can
37 // survive in the compilation cache, before it will be flushed if it
38 // hasn't been used.
39 NUMBER_OF_SCRIPT_GENERATIONS = 5,
40 35
41 // The compilation cache consists of tables - one for each entry 36 // The number of sub caches covering the different types to cache.
42 // kind plus extras for the script generations. 37 static const int kSubCacheCount = 4;
43 NUMBER_OF_TABLE_ENTRIES = 38
44 CompilationCache::LAST_ENTRY + NUMBER_OF_SCRIPT_GENERATIONS 39 // The number of generations for each sub cache.
40 static const int kScriptGenerations = 5;
41 static const int kEvalGlobalGenerations = 2;
42 static const int kEvalContextualGenerations = 2;
43 static const int kRegExpGenerations = 2;
44
45 // Initial of each compilation cache table allocated.
46 static const int kInitialCacheSize = 64;
47
48 // The compilation cache consists of several generational sub-caches which uses
49 // this class as a base class. A sub-cache contains a compilation cache tables
50 // for each generation of the sub-cache. As the same source code string has
51 // different compiled code for scripts and evals. Internally, we use separate
52 // sub-caches to avoid getting the wrong kind of result when looking up.
53 class CompilationSubCache {
54 public:
55 explicit CompilationSubCache(int generations): generations_(generations) {
56 tables_ = NewArray<Object*>(generations);
57 }
58
59 // Get the compilation cache tables for a specific generation.
60 Handle<CompilationCacheTable> GetTable(int generation);
61
62 // Age the sub-cache by evicting the oldest generation and creating a new
63 // young generation.
64 void Age();
65
66 // GC support.
67 void Iterate(ObjectVisitor* v);
68
69 // Clear this sub-cache evicting all its content.
70 void Clear();
71
72 // Number of generations in this sub-cache.
73 inline int generations() { return generations_; }
74
75 private:
76 int generations_; // Number of generations.
77 Object** tables_; // Compilation cache tables - one for each generation.
78
79 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
45 }; 80 };
46 81
47 82
83 // Sub-cache for scripts.
84 class CompilationCacheScript : public CompilationSubCache {
85 public:
86 explicit CompilationCacheScript(int generations)
87 : CompilationSubCache(generations) { }
88
89 Handle<JSFunction> Lookup(Handle<String> source,
90 Handle<Object> name,
91 int line_offset,
92 int column_offset);
93 void Put(Handle<String> source, Handle<JSFunction> boilerplate);
94
95 private:
96 bool HasOrigin(Handle<JSFunction> boilerplate,
97 Handle<Object> name,
98 int line_offset,
99 int column_offset);
100
101 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
102 };
103
104
105 // Sub-cache for eval scripts.
106 class CompilationCacheEval: public CompilationSubCache {
107 public:
108 explicit CompilationCacheEval(int generations)
109 : CompilationSubCache(generations) { }
110
111 Handle<JSFunction> Lookup(Handle<String> source, Handle<Context> context);
112
113 void Put(Handle<String> source,
114 Handle<Context> context,
115 Handle<JSFunction> boilerplate);
116
117 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
118 };
119
120
121 // Sub-cache for regular expressions.
122 class CompilationCacheRegExp: public CompilationSubCache {
123 public:
124 explicit CompilationCacheRegExp(int generations)
125 : CompilationSubCache(generations) { }
126
127 Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
128
129 void Put(Handle<String> source,
130 JSRegExp::Flags flags,
131 Handle<FixedArray> data);
132
133 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
134 };
135
136
137 // Statically allocate all the sub-caches.
138 static CompilationCacheScript script(kScriptGenerations);
139 static CompilationCacheEval eval_global(kEvalGlobalGenerations);
140 static CompilationCacheEval eval_contextual(kEvalContextualGenerations);
141 static CompilationCacheRegExp reg_exp(kRegExpGenerations);
142 static CompilationSubCache* subcaches[kSubCacheCount] =
143 {&script, &eval_global, &eval_contextual, &reg_exp};
144
145
48 // Current enable state of the compilation cache. 146 // Current enable state of the compilation cache.
49 static bool enabled = true; 147 static bool enabled = true;
50 static inline bool IsEnabled() { 148 static inline bool IsEnabled() {
51 return FLAG_compilation_cache && enabled; 149 return FLAG_compilation_cache && enabled;
52 } 150 }
53 151
54 // Keep separate tables for the different entry kinds.
55 static Object* tables[NUMBER_OF_TABLE_ENTRIES] = { 0, };
56
57 152
58 static Handle<CompilationCacheTable> AllocateTable(int size) { 153 static Handle<CompilationCacheTable> AllocateTable(int size) {
59 CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), 154 CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
60 CompilationCacheTable); 155 CompilationCacheTable);
61 } 156 }
62 157
63 158
64 static Handle<CompilationCacheTable> GetTable(int index) { 159 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
65 ASSERT(index >= 0 && index < NUMBER_OF_TABLE_ENTRIES); 160 ASSERT(generation < generations_);
66 Handle<CompilationCacheTable> result; 161 Handle<CompilationCacheTable> result;
67 if (tables[index]->IsUndefined()) { 162 if (tables_[generation]->IsUndefined()) {
68 static const int kInitialCacheSize = 64;
69 result = AllocateTable(kInitialCacheSize); 163 result = AllocateTable(kInitialCacheSize);
70 tables[index] = *result; 164 tables_[generation] = *result;
71 } else { 165 } else {
72 CompilationCacheTable* table = CompilationCacheTable::cast(tables[index]); 166 CompilationCacheTable* table =
167 CompilationCacheTable::cast(tables_[generation]);
73 result = Handle<CompilationCacheTable>(table); 168 result = Handle<CompilationCacheTable>(table);
74 } 169 }
75 return result; 170 return result;
76 } 171 }
77 172
78 173
79 static Handle<JSFunction> Lookup(Handle<String> source, 174 void CompilationSubCache::Age() {
80 Handle<Context> context, 175 // Age the generations implicitly killing off the oldest.
81 CompilationCache::Entry entry) { 176 for (int i = generations_ - 1; i > 0; i--) {
82 // Make sure not to leak the table into the surrounding handle 177 tables_[i] = tables_[i - 1];
83 // scope. Otherwise, we risk keeping old tables around even after
84 // having cleared the cache.
85 Object* result;
86 { HandleScope scope;
87 Handle<CompilationCacheTable> table = GetTable(entry);
88 result = table->LookupEval(*source, *context);
89 } 178 }
90 if (result->IsJSFunction()) { 179
91 return Handle<JSFunction>(JSFunction::cast(result)); 180 // Set the first generation as unborn.
92 } else { 181 tables_[0] = Heap::undefined_value();
93 return Handle<JSFunction>::null();
94 }
95 } 182 }
96 183
97 184
98 static Handle<FixedArray> Lookup(Handle<String> source, 185 void CompilationSubCache::Iterate(ObjectVisitor* v) {
99 JSRegExp::Flags flags) { 186 v->VisitPointers(&tables_[0], &tables_[generations_]);
100 // Make sure not to leak the table into the surrounding handle 187 }
101 // scope. Otherwise, we risk keeping old tables around even after 188
102 // having cleared the cache. 189
103 Object* result; 190 void CompilationSubCache::Clear() {
104 { HandleScope scope; 191 for (int i = 0; i < generations_; i++) {
105 Handle<CompilationCacheTable> table = GetTable(CompilationCache::REGEXP); 192 tables_[i] = Heap::undefined_value();
106 result = table->LookupRegExp(*source, flags);
107 }
108 if (result->IsFixedArray()) {
109 return Handle<FixedArray>(FixedArray::cast(result));
110 } else {
111 return Handle<FixedArray>::null();
112 } 193 }
113 } 194 }
114 195
115 196
116 // We only re-use a cached function for some script source code if the 197 // We only re-use a cached function for some script source code if the
117 // script originates from the same place. This is to avoid issues 198 // script originates from the same place. This is to avoid issues
118 // when reporting errors, etc. 199 // when reporting errors, etc.
119 static bool HasOrigin(Handle<JSFunction> boilerplate, 200 bool CompilationCacheScript::HasOrigin(Handle<JSFunction> boilerplate,
120 Handle<Object> name, 201 Handle<Object> name,
121 int line_offset, 202 int line_offset,
122 int column_offset) { 203 int column_offset) {
123 Handle<Script> script = 204 Handle<Script> script =
124 Handle<Script>(Script::cast(boilerplate->shared()->script())); 205 Handle<Script>(Script::cast(boilerplate->shared()->script()));
125 // If the script name isn't set, the boilerplate script should have 206 // If the script name isn't set, the boilerplate script should have
126 // an undefined name to have the same origin. 207 // an undefined name to have the same origin.
127 if (name.is_null()) { 208 if (name.is_null()) {
128 return script->name()->IsUndefined(); 209 return script->name()->IsUndefined();
129 } 210 }
130 // Do the fast bailout checks first. 211 // Do the fast bailout checks first.
131 if (line_offset != script->line_offset()->value()) return false; 212 if (line_offset != script->line_offset()->value()) return false;
132 if (column_offset != script->column_offset()->value()) return false; 213 if (column_offset != script->column_offset()->value()) return false;
133 // Check that both names are strings. If not, no match. 214 // Check that both names are strings. If not, no match.
134 if (!name->IsString() || !script->name()->IsString()) return false; 215 if (!name->IsString() || !script->name()->IsString()) return false;
135 // Compare the two name strings for equality. 216 // Compare the two name strings for equality.
136 return String::cast(*name)->Equals(String::cast(script->name())); 217 return String::cast(*name)->Equals(String::cast(script->name()));
137 } 218 }
138 219
139 220
140 // TODO(245): Need to allow identical code from different contexts to 221 // TODO(245): Need to allow identical code from different contexts to
141 // be cached in the same script generation. Currently the first use 222 // be cached in the same script generation. Currently the first use
142 // will be cached, but subsequent code from different source / line 223 // will be cached, but subsequent code from different source / line
143 // won't. 224 // won't.
144 Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source, 225 Handle<JSFunction> CompilationCacheScript::Lookup(Handle<String> source,
145 Handle<Object> name, 226 Handle<Object> name,
146 int line_offset, 227 int line_offset,
147 int column_offset) { 228 int column_offset) {
148 if (!IsEnabled()) {
149 return Handle<JSFunction>::null();
150 }
151
152 // Use an int for the generation index, so value range propagation
153 // in gcc 4.3+ won't assume it can only go up to LAST_ENTRY when in
154 // fact it can go up to SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS.
155 int generation = SCRIPT;
156 Object* result = NULL; 229 Object* result = NULL;
230 int generation;
157 231
158 // Probe the script generation tables. Make sure not to leak handles 232 // Probe the script generation tables. Make sure not to leak handles
159 // into the caller's handle scope. 233 // into the caller's handle scope.
160 { HandleScope scope; 234 { HandleScope scope;
161 while (generation < SCRIPT + NUMBER_OF_SCRIPT_GENERATIONS) { 235 for (generation = 0; generation < generations(); generation++) {
162 Handle<CompilationCacheTable> table = GetTable(generation); 236 Handle<CompilationCacheTable> table = GetTable(generation);
163 Handle<Object> probe(table->Lookup(*source)); 237 Handle<Object> probe(table->Lookup(*source));
164 if (probe->IsJSFunction()) { 238 if (probe->IsJSFunction()) {
165 Handle<JSFunction> boilerplate = Handle<JSFunction>::cast(probe); 239 Handle<JSFunction> boilerplate = Handle<JSFunction>::cast(probe);
166 // Break when we've found a suitable boilerplate function that 240 // Break when we've found a suitable boilerplate function that
167 // matches the origin. 241 // matches the origin.
168 if (HasOrigin(boilerplate, name, line_offset, column_offset)) { 242 if (HasOrigin(boilerplate, name, line_offset, column_offset)) {
169 result = *boilerplate; 243 result = *boilerplate;
170 break; 244 break;
171 } 245 }
172 } 246 }
173 // Go to the next generation.
174 generation++;
175 } 247 }
176 } 248 }
177 249
178 static void* script_histogram = StatsTable::CreateHistogram( 250 static void* script_histogram = StatsTable::CreateHistogram(
179 "V8.ScriptCache", 251 "V8.ScriptCache",
180 0, 252 0,
181 NUMBER_OF_SCRIPT_GENERATIONS, 253 kScriptGenerations,
182 NUMBER_OF_SCRIPT_GENERATIONS + 1); 254 kScriptGenerations + 1);
183 255
184 if (script_histogram != NULL) { 256 if (script_histogram != NULL) {
185 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. 257 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
186 StatsTable::AddHistogramSample(script_histogram, generation - SCRIPT); 258 StatsTable::AddHistogramSample(script_histogram, generation);
187 } 259 }
188 260
189 // Once outside the manacles of the handle scope, we need to recheck 261 // Once outside the manacles of the handle scope, we need to recheck
190 // to see if we actually found a cached script. If so, we return a 262 // to see if we actually found a cached script. If so, we return a
191 // handle created in the caller's handle scope. 263 // handle created in the caller's handle scope.
192 if (result != NULL) { 264 if (result != NULL) {
193 Handle<JSFunction> boilerplate(JSFunction::cast(result)); 265 Handle<JSFunction> boilerplate(JSFunction::cast(result));
194 ASSERT(HasOrigin(boilerplate, name, line_offset, column_offset)); 266 ASSERT(HasOrigin(boilerplate, name, line_offset, column_offset));
195 // If the script was found in a later generation, we promote it to 267 // If the script was found in a later generation, we promote it to
196 // the first generation to let it survive longer in the cache. 268 // the first generation to let it survive longer in the cache.
197 if (generation != SCRIPT) PutScript(source, boilerplate); 269 if (generation != 0) Put(source, boilerplate);
198 Counters::compilation_cache_hits.Increment(); 270 Counters::compilation_cache_hits.Increment();
199 return boilerplate; 271 return boilerplate;
200 } else { 272 } else {
201 Counters::compilation_cache_misses.Increment(); 273 Counters::compilation_cache_misses.Increment();
202 return Handle<JSFunction>::null(); 274 return Handle<JSFunction>::null();
203 } 275 }
204 } 276 }
205 277
206 278
279 void CompilationCacheScript::Put(Handle<String> source,
280 Handle<JSFunction> boilerplate) {
281 HandleScope scope;
282 ASSERT(boilerplate->IsBoilerplate());
283 Handle<CompilationCacheTable> table = GetTable(0);
284 CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
285 }
286
287
288 Handle<JSFunction> CompilationCacheEval::Lookup(Handle<String> source,
289 Handle<Context> context) {
290 // Make sure not to leak the table into the surrounding handle
291 // scope. Otherwise, we risk keeping old tables around even after
292 // having cleared the cache.
293 Object* result = NULL;
294 int generation;
295 { HandleScope scope;
296 for (generation = 0; generation < generations(); generation++) {
297 Handle<CompilationCacheTable> table = GetTable(generation);
298 result = table->LookupEval(*source, *context);
299 if (result->IsJSFunction()) {
300 break;
301 }
302 }
303 }
304 if (result->IsJSFunction()) {
305 Handle<JSFunction> boilerplate(JSFunction::cast(result));
306 if (generation != 0) {
307 Put(source, context, boilerplate);
308 }
309 Counters::compilation_cache_hits.Increment();
310 return boilerplate;
311 } else {
312 Counters::compilation_cache_misses.Increment();
313 return Handle<JSFunction>::null();
314 }
315 }
316
317
318 void CompilationCacheEval::Put(Handle<String> source,
319 Handle<Context> context,
320 Handle<JSFunction> boilerplate) {
321 HandleScope scope;
322 ASSERT(boilerplate->IsBoilerplate());
323 Handle<CompilationCacheTable> table = GetTable(0);
324 CALL_HEAP_FUNCTION_VOID(table->PutEval(*source, *context, *boilerplate));
325 }
326
327
328 Handle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
329 JSRegExp::Flags flags) {
330 // Make sure not to leak the table into the surrounding handle
331 // scope. Otherwise, we risk keeping old tables around even after
332 // having cleared the cache.
333 Object* result = NULL;
334 int generation;
335 { HandleScope scope;
336 for (generation = 0; generation < generations(); generation++) {
337 Handle<CompilationCacheTable> table = GetTable(generation);
338 result = table->LookupRegExp(*source, flags);
339 if (result->IsFixedArray()) {
340 break;
341 }
342 }
343 }
344 if (result->IsFixedArray()) {
345 Handle<FixedArray> data(FixedArray::cast(result));
346 if (generation != 0) {
347 Put(source, flags, data);
348 }
349 Counters::compilation_cache_hits.Increment();
350 return data;
351 } else {
352 Counters::compilation_cache_misses.Increment();
353 return Handle<FixedArray>::null();
354 }
355 }
356
357
358 void CompilationCacheRegExp::Put(Handle<String> source,
359 JSRegExp::Flags flags,
360 Handle<FixedArray> data) {
361 HandleScope scope;
362 Handle<CompilationCacheTable> table = GetTable(0);
363 CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
364 }
365
366
367 Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
368 Handle<Object> name,
369 int line_offset,
370 int column_offset) {
371 if (!IsEnabled()) {
372 return Handle<JSFunction>::null();
373 }
374
375 return script.Lookup(source, name, line_offset, column_offset);
376 }
377
378
207 Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source, 379 Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
208 Handle<Context> context, 380 Handle<Context> context,
209 Entry entry) { 381 bool is_global) {
210 if (!IsEnabled()) { 382 if (!IsEnabled()) {
211 return Handle<JSFunction>::null(); 383 return Handle<JSFunction>::null();
212 } 384 }
213 385
214 ASSERT(entry == EVAL_GLOBAL || entry == EVAL_CONTEXTUAL); 386 Handle<JSFunction> result;
215 Handle<JSFunction> result = Lookup(source, context, entry); 387 if (is_global) {
216 if (result.is_null()) { 388 result = eval_global.Lookup(source, context);
217 Counters::compilation_cache_misses.Increment();
218 } else { 389 } else {
219 Counters::compilation_cache_hits.Increment(); 390 result = eval_contextual.Lookup(source, context);
220 } 391 }
221 return result; 392 return result;
222 } 393 }
223 394
224 395
225 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, 396 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
226 JSRegExp::Flags flags) { 397 JSRegExp::Flags flags) {
227 if (!IsEnabled()) { 398 if (!IsEnabled()) {
228 return Handle<FixedArray>::null(); 399 return Handle<FixedArray>::null();
229 } 400 }
230 401
231 Handle<FixedArray> result = Lookup(source, flags); 402 return reg_exp.Lookup(source, flags);
232 if (result.is_null()) {
233 Counters::compilation_cache_misses.Increment();
234 } else {
235 Counters::compilation_cache_hits.Increment();
236 }
237 return result;
238 } 403 }
239 404
240 405
241 void CompilationCache::PutScript(Handle<String> source, 406 void CompilationCache::PutScript(Handle<String> source,
242 Handle<JSFunction> boilerplate) { 407 Handle<JSFunction> boilerplate) {
243 if (!IsEnabled()) { 408 if (!IsEnabled()) {
244 return; 409 return;
245 } 410 }
246 411
247 HandleScope scope;
248 ASSERT(boilerplate->IsBoilerplate()); 412 ASSERT(boilerplate->IsBoilerplate());
249 Handle<CompilationCacheTable> table = GetTable(SCRIPT); 413 script.Put(source, boilerplate);
250 CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
251 } 414 }
252 415
253 416
254 void CompilationCache::PutEval(Handle<String> source, 417 void CompilationCache::PutEval(Handle<String> source,
255 Handle<Context> context, 418 Handle<Context> context,
256 Entry entry, 419 bool is_global,
257 Handle<JSFunction> boilerplate) { 420 Handle<JSFunction> boilerplate) {
258 if (!IsEnabled()) { 421 if (!IsEnabled()) {
259 return; 422 return;
260 } 423 }
261 424
262 HandleScope scope; 425 HandleScope scope;
263 ASSERT(boilerplate->IsBoilerplate()); 426 ASSERT(boilerplate->IsBoilerplate());
264 Handle<CompilationCacheTable> table = GetTable(entry); 427 if (is_global) {
265 CALL_HEAP_FUNCTION_VOID(table->PutEval(*source, *context, *boilerplate)); 428 eval_global.Put(source, context, boilerplate);
429 } else {
430 eval_contextual.Put(source, context, boilerplate);
431 }
266 } 432 }
267 433
268 434
269 435
270 void CompilationCache::PutRegExp(Handle<String> source, 436 void CompilationCache::PutRegExp(Handle<String> source,
271 JSRegExp::Flags flags, 437 JSRegExp::Flags flags,
272 Handle<FixedArray> data) { 438 Handle<FixedArray> data) {
273 if (!IsEnabled()) { 439 if (!IsEnabled()) {
274 return; 440 return;
275 } 441 }
276 442
277 HandleScope scope; 443 reg_exp.Put(source, flags, data);
278 Handle<CompilationCacheTable> table = GetTable(REGEXP);
279 CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
280 } 444 }
281 445
282 446
283 void CompilationCache::Clear() { 447 void CompilationCache::Clear() {
284 for (int i = 0; i < NUMBER_OF_TABLE_ENTRIES; i++) { 448 for (int i = 0; i < kSubCacheCount; i++) {
285 tables[i] = Heap::undefined_value(); 449 subcaches[i]->Clear();
286 } 450 }
287 } 451 }
288 452
289 453
290 void CompilationCache::Iterate(ObjectVisitor* v) { 454 void CompilationCache::Iterate(ObjectVisitor* v) {
291 v->VisitPointers(&tables[0], &tables[NUMBER_OF_TABLE_ENTRIES]); 455 for (int i = 0; i < kSubCacheCount; i++) {
456 subcaches[i]->Iterate(v);
457 }
292 } 458 }
293 459
294 460
295 void CompilationCache::MarkCompactPrologue() { 461 void CompilationCache::MarkCompactPrologue() {
296 ASSERT(LAST_ENTRY == SCRIPT); 462 for (int i = 0; i < kSubCacheCount; i++) {
297 for (int i = NUMBER_OF_TABLE_ENTRIES - 1; i > SCRIPT; i--) { 463 subcaches[i]->Age();
298 tables[i] = tables[i - 1];
299 }
300 for (int j = 0; j <= LAST_ENTRY; j++) {
301 tables[j] = Heap::undefined_value();
302 } 464 }
303 } 465 }
304 466
305 467
306 void CompilationCache::Enable() { 468 void CompilationCache::Enable() {
307 enabled = true; 469 enabled = true;
308 } 470 }
309 471
310 472
311 void CompilationCache::Disable() { 473 void CompilationCache::Disable() {
312 enabled = false; 474 enabled = false;
313 Clear(); 475 Clear();
314 } 476 }
315 477
316 478
317 } } // namespace v8::internal 479 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compilation-cache.h ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698