OLD | NEW |
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 15 matching lines...) Expand all Loading... |
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 #include "serialize.h" | 31 #include "serialize.h" |
32 | 32 |
33 namespace v8 { | 33 namespace v8 { |
34 namespace internal { | 34 namespace internal { |
35 | 35 |
36 // The number of sub caches covering the different types to cache. | |
37 static const int kSubCacheCount = 4; | |
38 | 36 |
39 // The number of generations for each sub cache. | 37 // The number of generations for each sub cache. |
40 // The number of ScriptGenerations is carefully chosen based on histograms. | 38 // The number of ScriptGenerations is carefully chosen based on histograms. |
41 // See issue 458: http://code.google.com/p/v8/issues/detail?id=458 | 39 // See issue 458: http://code.google.com/p/v8/issues/detail?id=458 |
42 static const int kScriptGenerations = 5; | 40 static const int kScriptGenerations = 5; |
43 static const int kEvalGlobalGenerations = 2; | 41 static const int kEvalGlobalGenerations = 2; |
44 static const int kEvalContextualGenerations = 2; | 42 static const int kEvalContextualGenerations = 2; |
45 static const int kRegExpGenerations = 2; | 43 static const int kRegExpGenerations = 2; |
46 | 44 |
47 // Initial size of each compilation cache table allocated. | 45 // Initial size of each compilation cache table allocated. |
48 static const int kInitialCacheSize = 64; | 46 static const int kInitialCacheSize = 64; |
49 | 47 |
50 // Index for the first generation in the cache. | |
51 static const int kFirstGeneration = 0; | |
52 | 48 |
53 // The compilation cache consists of several generational sub-caches which uses | 49 CompilationCache::CompilationCache() |
54 // this class as a base class. A sub-cache contains a compilation cache tables | 50 : script_(kScriptGenerations), |
55 // for each generation of the sub-cache. Since the same source code string has | 51 eval_global_(kEvalGlobalGenerations), |
56 // different compiled code for scripts and evals, we use separate sub-caches | 52 eval_contextual_(kEvalContextualGenerations), |
57 // for different compilation modes, to avoid retrieving the wrong result. | 53 reg_exp_(kRegExpGenerations), |
58 class CompilationSubCache { | 54 enabled_(true), |
59 public: | 55 eager_optimizing_set_(NULL) { |
60 explicit CompilationSubCache(int generations): generations_(generations) { | 56 CompilationSubCache* subcaches[kSubCacheCount] = |
61 tables_ = NewArray<Object*>(generations); | 57 {&script_, &eval_global_, &eval_contextual_, ®_exp_}; |
| 58 for (int i = 0; i < kSubCacheCount; ++i) { |
| 59 subcaches_[i] = subcaches[i]; |
62 } | 60 } |
63 | 61 } |
64 ~CompilationSubCache() { DeleteArray(tables_); } | |
65 | |
66 // Get the compilation cache tables for a specific generation. | |
67 Handle<CompilationCacheTable> GetTable(int generation); | |
68 | |
69 // Accessors for first generation. | |
70 Handle<CompilationCacheTable> GetFirstTable() { | |
71 return GetTable(kFirstGeneration); | |
72 } | |
73 void SetFirstTable(Handle<CompilationCacheTable> value) { | |
74 ASSERT(kFirstGeneration < generations_); | |
75 tables_[kFirstGeneration] = *value; | |
76 } | |
77 | |
78 // Age the sub-cache by evicting the oldest generation and creating a new | |
79 // young generation. | |
80 void Age(); | |
81 | |
82 // GC support. | |
83 void Iterate(ObjectVisitor* v); | |
84 void IterateFunctions(ObjectVisitor* v); | |
85 | |
86 // Clear this sub-cache evicting all its content. | |
87 void Clear(); | |
88 | |
89 // Remove given shared function info from sub-cache. | |
90 void Remove(Handle<SharedFunctionInfo> function_info); | |
91 | |
92 // Number of generations in this sub-cache. | |
93 inline int generations() { return generations_; } | |
94 | |
95 private: | |
96 int generations_; // Number of generations. | |
97 Object** tables_; // Compilation cache tables - one for each generation. | |
98 | |
99 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache); | |
100 }; | |
101 | 62 |
102 | 63 |
103 // Sub-cache for scripts. | 64 CompilationCache::~CompilationCache() { |
104 class CompilationCacheScript : public CompilationSubCache { | 65 delete eager_optimizing_set_; |
105 public: | 66 eager_optimizing_set_ = NULL; |
106 explicit CompilationCacheScript(int generations) | |
107 : CompilationSubCache(generations) { } | |
108 | |
109 Handle<SharedFunctionInfo> Lookup(Handle<String> source, | |
110 Handle<Object> name, | |
111 int line_offset, | |
112 int column_offset); | |
113 void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info); | |
114 | |
115 private: | |
116 MUST_USE_RESULT MaybeObject* TryTablePut( | |
117 Handle<String> source, Handle<SharedFunctionInfo> function_info); | |
118 | |
119 // Note: Returns a new hash table if operation results in expansion. | |
120 Handle<CompilationCacheTable> TablePut( | |
121 Handle<String> source, Handle<SharedFunctionInfo> function_info); | |
122 | |
123 bool HasOrigin(Handle<SharedFunctionInfo> function_info, | |
124 Handle<Object> name, | |
125 int line_offset, | |
126 int column_offset); | |
127 | |
128 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript); | |
129 }; | |
130 | |
131 | |
132 // Sub-cache for eval scripts. | |
133 class CompilationCacheEval: public CompilationSubCache { | |
134 public: | |
135 explicit CompilationCacheEval(int generations) | |
136 : CompilationSubCache(generations) { } | |
137 | |
138 Handle<SharedFunctionInfo> Lookup(Handle<String> source, | |
139 Handle<Context> context, | |
140 StrictModeFlag strict_mode); | |
141 | |
142 void Put(Handle<String> source, | |
143 Handle<Context> context, | |
144 Handle<SharedFunctionInfo> function_info); | |
145 | |
146 private: | |
147 MUST_USE_RESULT MaybeObject* TryTablePut( | |
148 Handle<String> source, | |
149 Handle<Context> context, | |
150 Handle<SharedFunctionInfo> function_info); | |
151 | |
152 | |
153 // Note: Returns a new hash table if operation results in expansion. | |
154 Handle<CompilationCacheTable> TablePut( | |
155 Handle<String> source, | |
156 Handle<Context> context, | |
157 Handle<SharedFunctionInfo> function_info); | |
158 | |
159 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); | |
160 }; | |
161 | |
162 | |
163 // Sub-cache for regular expressions. | |
164 class CompilationCacheRegExp: public CompilationSubCache { | |
165 public: | |
166 explicit CompilationCacheRegExp(int generations) | |
167 : CompilationSubCache(generations) { } | |
168 | |
169 Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); | |
170 | |
171 void Put(Handle<String> source, | |
172 JSRegExp::Flags flags, | |
173 Handle<FixedArray> data); | |
174 private: | |
175 MUST_USE_RESULT MaybeObject* TryTablePut(Handle<String> source, | |
176 JSRegExp::Flags flags, | |
177 Handle<FixedArray> data); | |
178 | |
179 // Note: Returns a new hash table if operation results in expansion. | |
180 Handle<CompilationCacheTable> TablePut(Handle<String> source, | |
181 JSRegExp::Flags flags, | |
182 Handle<FixedArray> data); | |
183 | |
184 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); | |
185 }; | |
186 | |
187 | |
188 // Statically allocate all the sub-caches. | |
189 static CompilationCacheScript script(kScriptGenerations); | |
190 static CompilationCacheEval eval_global(kEvalGlobalGenerations); | |
191 static CompilationCacheEval eval_contextual(kEvalContextualGenerations); | |
192 static CompilationCacheRegExp reg_exp(kRegExpGenerations); | |
193 static CompilationSubCache* subcaches[kSubCacheCount] = | |
194 {&script, &eval_global, &eval_contextual, ®_exp}; | |
195 | |
196 | |
197 // Current enable state of the compilation cache. | |
198 static bool enabled = true; | |
199 static inline bool IsEnabled() { | |
200 return FLAG_compilation_cache && enabled; | |
201 } | 67 } |
202 | 68 |
203 | 69 |
204 static Handle<CompilationCacheTable> AllocateTable(int size) { | 70 static Handle<CompilationCacheTable> AllocateTable(int size) { |
205 CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), | 71 Isolate* isolate = Isolate::Current(); |
| 72 CALL_HEAP_FUNCTION(isolate, |
| 73 CompilationCacheTable::Allocate(size), |
206 CompilationCacheTable); | 74 CompilationCacheTable); |
207 } | 75 } |
208 | 76 |
209 | 77 |
210 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { | 78 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { |
211 ASSERT(generation < generations_); | 79 ASSERT(generation < generations_); |
212 Handle<CompilationCacheTable> result; | 80 Handle<CompilationCacheTable> result; |
213 if (tables_[generation]->IsUndefined()) { | 81 if (tables_[generation]->IsUndefined()) { |
214 result = AllocateTable(kInitialCacheSize); | 82 result = AllocateTable(kInitialCacheSize); |
215 tables_[generation] = *result; | 83 tables_[generation] = *result; |
216 } else { | 84 } else { |
217 CompilationCacheTable* table = | 85 CompilationCacheTable* table = |
218 CompilationCacheTable::cast(tables_[generation]); | 86 CompilationCacheTable::cast(tables_[generation]); |
219 result = Handle<CompilationCacheTable>(table); | 87 result = Handle<CompilationCacheTable>(table); |
220 } | 88 } |
221 return result; | 89 return result; |
222 } | 90 } |
223 | 91 |
224 | |
225 void CompilationSubCache::Age() { | 92 void CompilationSubCache::Age() { |
226 // Age the generations implicitly killing off the oldest. | 93 // Age the generations implicitly killing off the oldest. |
227 for (int i = generations_ - 1; i > 0; i--) { | 94 for (int i = generations_ - 1; i > 0; i--) { |
228 tables_[i] = tables_[i - 1]; | 95 tables_[i] = tables_[i - 1]; |
229 } | 96 } |
230 | 97 |
231 // Set the first generation as unborn. | 98 // Set the first generation as unborn. |
232 tables_[0] = Heap::undefined_value(); | 99 tables_[0] = HEAP->undefined_value(); |
233 } | 100 } |
234 | 101 |
235 | 102 |
236 void CompilationSubCache::IterateFunctions(ObjectVisitor* v) { | 103 void CompilationSubCache::IterateFunctions(ObjectVisitor* v) { |
237 Object* undefined = Heap::raw_unchecked_undefined_value(); | 104 Object* undefined = HEAP->raw_unchecked_undefined_value(); |
238 for (int i = 0; i < generations_; i++) { | 105 for (int i = 0; i < generations_; i++) { |
239 if (tables_[i] != undefined) { | 106 if (tables_[i] != undefined) { |
240 reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v); | 107 reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v); |
241 } | 108 } |
242 } | 109 } |
243 } | 110 } |
244 | 111 |
245 | 112 |
246 void CompilationSubCache::Iterate(ObjectVisitor* v) { | 113 void CompilationSubCache::Iterate(ObjectVisitor* v) { |
247 v->VisitPointers(&tables_[0], &tables_[generations_]); | 114 v->VisitPointers(&tables_[0], &tables_[generations_]); |
248 } | 115 } |
249 | 116 |
250 | 117 |
251 void CompilationSubCache::Clear() { | 118 void CompilationSubCache::Clear() { |
252 MemsetPointer(tables_, Heap::undefined_value(), generations_); | 119 MemsetPointer(tables_, HEAP->undefined_value(), generations_); |
253 } | 120 } |
254 | 121 |
255 | 122 |
256 void CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) { | 123 void CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) { |
257 // Probe the script generation tables. Make sure not to leak handles | 124 // Probe the script generation tables. Make sure not to leak handles |
258 // into the caller's handle scope. | 125 // into the caller's handle scope. |
259 { HandleScope scope; | 126 { HandleScope scope; |
260 for (int generation = 0; generation < generations(); generation++) { | 127 for (int generation = 0; generation < generations(); generation++) { |
261 Handle<CompilationCacheTable> table = GetTable(generation); | 128 Handle<CompilationCacheTable> table = GetTable(generation); |
262 table->Remove(*function_info); | 129 table->Remove(*function_info); |
263 } | 130 } |
264 } | 131 } |
265 } | 132 } |
266 | 133 |
267 | 134 |
| 135 CompilationCacheScript::CompilationCacheScript(int generations) |
| 136 : CompilationSubCache(generations), |
| 137 script_histogram_(NULL), |
| 138 script_histogram_initialized_(false) { |
| 139 } |
| 140 |
| 141 |
268 // We only re-use a cached function for some script source code if the | 142 // We only re-use a cached function for some script source code if the |
269 // script originates from the same place. This is to avoid issues | 143 // script originates from the same place. This is to avoid issues |
270 // when reporting errors, etc. | 144 // when reporting errors, etc. |
271 bool CompilationCacheScript::HasOrigin( | 145 bool CompilationCacheScript::HasOrigin( |
272 Handle<SharedFunctionInfo> function_info, | 146 Handle<SharedFunctionInfo> function_info, |
273 Handle<Object> name, | 147 Handle<Object> name, |
274 int line_offset, | 148 int line_offset, |
275 int column_offset) { | 149 int column_offset) { |
276 Handle<Script> script = | 150 Handle<Script> script = |
277 Handle<Script>(Script::cast(function_info->script())); | 151 Handle<Script>(Script::cast(function_info->script())); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 // Break when we've found a suitable shared function info that | 187 // Break when we've found a suitable shared function info that |
314 // matches the origin. | 188 // matches the origin. |
315 if (HasOrigin(function_info, name, line_offset, column_offset)) { | 189 if (HasOrigin(function_info, name, line_offset, column_offset)) { |
316 result = *function_info; | 190 result = *function_info; |
317 break; | 191 break; |
318 } | 192 } |
319 } | 193 } |
320 } | 194 } |
321 } | 195 } |
322 | 196 |
323 static void* script_histogram = StatsTable::CreateHistogram( | 197 Isolate* isolate = Isolate::Current(); |
324 "V8.ScriptCache", | 198 if (!script_histogram_initialized_) { |
325 0, | 199 script_histogram_ = isolate->stats_table()->CreateHistogram( |
326 kScriptGenerations, | 200 "V8.ScriptCache", |
327 kScriptGenerations + 1); | 201 0, |
| 202 kScriptGenerations, |
| 203 kScriptGenerations + 1); |
| 204 script_histogram_initialized_ = true; |
| 205 } |
328 | 206 |
329 if (script_histogram != NULL) { | 207 if (script_histogram_ != NULL) { |
330 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. | 208 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. |
331 StatsTable::AddHistogramSample(script_histogram, generation); | 209 isolate->stats_table()->AddHistogramSample(script_histogram_, generation); |
332 } | 210 } |
333 | 211 |
334 // Once outside the manacles of the handle scope, we need to recheck | 212 // Once outside the manacles of the handle scope, we need to recheck |
335 // to see if we actually found a cached script. If so, we return a | 213 // to see if we actually found a cached script. If so, we return a |
336 // handle created in the caller's handle scope. | 214 // handle created in the caller's handle scope. |
337 if (result != NULL) { | 215 if (result != NULL) { |
338 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); | 216 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); |
339 ASSERT(HasOrigin(shared, name, line_offset, column_offset)); | 217 ASSERT(HasOrigin(shared, name, line_offset, column_offset)); |
340 // If the script was found in a later generation, we promote it to | 218 // If the script was found in a later generation, we promote it to |
341 // the first generation to let it survive longer in the cache. | 219 // the first generation to let it survive longer in the cache. |
342 if (generation != 0) Put(source, shared); | 220 if (generation != 0) Put(source, shared); |
343 Counters::compilation_cache_hits.Increment(); | 221 isolate->counters()->compilation_cache_hits()->Increment(); |
344 return shared; | 222 return shared; |
345 } else { | 223 } else { |
346 Counters::compilation_cache_misses.Increment(); | 224 isolate->counters()->compilation_cache_misses()->Increment(); |
347 return Handle<SharedFunctionInfo>::null(); | 225 return Handle<SharedFunctionInfo>::null(); |
348 } | 226 } |
349 } | 227 } |
350 | 228 |
351 | 229 |
352 MaybeObject* CompilationCacheScript::TryTablePut( | 230 MaybeObject* CompilationCacheScript::TryTablePut( |
353 Handle<String> source, | 231 Handle<String> source, |
354 Handle<SharedFunctionInfo> function_info) { | 232 Handle<SharedFunctionInfo> function_info) { |
355 Handle<CompilationCacheTable> table = GetFirstTable(); | 233 Handle<CompilationCacheTable> table = GetFirstTable(); |
356 return table->Put(*source, *function_info); | 234 return table->Put(*source, *function_info); |
357 } | 235 } |
358 | 236 |
359 | 237 |
360 Handle<CompilationCacheTable> CompilationCacheScript::TablePut( | 238 Handle<CompilationCacheTable> CompilationCacheScript::TablePut( |
361 Handle<String> source, | 239 Handle<String> source, |
362 Handle<SharedFunctionInfo> function_info) { | 240 Handle<SharedFunctionInfo> function_info) { |
363 CALL_HEAP_FUNCTION(TryTablePut(source, function_info), CompilationCacheTable); | 241 Isolate* isolate = Isolate::Current(); |
| 242 CALL_HEAP_FUNCTION(isolate, |
| 243 TryTablePut(source, function_info), |
| 244 CompilationCacheTable); |
364 } | 245 } |
365 | 246 |
366 | 247 |
367 void CompilationCacheScript::Put(Handle<String> source, | 248 void CompilationCacheScript::Put(Handle<String> source, |
368 Handle<SharedFunctionInfo> function_info) { | 249 Handle<SharedFunctionInfo> function_info) { |
369 HandleScope scope; | 250 HandleScope scope; |
370 SetFirstTable(TablePut(source, function_info)); | 251 SetFirstTable(TablePut(source, function_info)); |
371 } | 252 } |
372 | 253 |
373 | 254 |
(...skipping 14 matching lines...) Expand all Loading... |
388 break; | 269 break; |
389 } | 270 } |
390 } | 271 } |
391 } | 272 } |
392 if (result->IsSharedFunctionInfo()) { | 273 if (result->IsSharedFunctionInfo()) { |
393 Handle<SharedFunctionInfo> | 274 Handle<SharedFunctionInfo> |
394 function_info(SharedFunctionInfo::cast(result)); | 275 function_info(SharedFunctionInfo::cast(result)); |
395 if (generation != 0) { | 276 if (generation != 0) { |
396 Put(source, context, function_info); | 277 Put(source, context, function_info); |
397 } | 278 } |
398 Counters::compilation_cache_hits.Increment(); | 279 COUNTERS->compilation_cache_hits()->Increment(); |
399 return function_info; | 280 return function_info; |
400 } else { | 281 } else { |
401 Counters::compilation_cache_misses.Increment(); | 282 COUNTERS->compilation_cache_misses()->Increment(); |
402 return Handle<SharedFunctionInfo>::null(); | 283 return Handle<SharedFunctionInfo>::null(); |
403 } | 284 } |
404 } | 285 } |
405 | 286 |
406 | 287 |
407 MaybeObject* CompilationCacheEval::TryTablePut( | 288 MaybeObject* CompilationCacheEval::TryTablePut( |
408 Handle<String> source, | 289 Handle<String> source, |
409 Handle<Context> context, | 290 Handle<Context> context, |
410 Handle<SharedFunctionInfo> function_info) { | 291 Handle<SharedFunctionInfo> function_info) { |
411 Handle<CompilationCacheTable> table = GetFirstTable(); | 292 Handle<CompilationCacheTable> table = GetFirstTable(); |
412 return table->PutEval(*source, *context, *function_info); | 293 return table->PutEval(*source, *context, *function_info); |
413 } | 294 } |
414 | 295 |
415 | 296 |
416 Handle<CompilationCacheTable> CompilationCacheEval::TablePut( | 297 Handle<CompilationCacheTable> CompilationCacheEval::TablePut( |
417 Handle<String> source, | 298 Handle<String> source, |
418 Handle<Context> context, | 299 Handle<Context> context, |
419 Handle<SharedFunctionInfo> function_info) { | 300 Handle<SharedFunctionInfo> function_info) { |
420 CALL_HEAP_FUNCTION(TryTablePut(source, context, function_info), | 301 Isolate* isolate = Isolate::Current(); |
| 302 CALL_HEAP_FUNCTION(isolate, |
| 303 TryTablePut(source, context, function_info), |
421 CompilationCacheTable); | 304 CompilationCacheTable); |
422 } | 305 } |
423 | 306 |
424 | 307 |
425 void CompilationCacheEval::Put(Handle<String> source, | 308 void CompilationCacheEval::Put(Handle<String> source, |
426 Handle<Context> context, | 309 Handle<Context> context, |
427 Handle<SharedFunctionInfo> function_info) { | 310 Handle<SharedFunctionInfo> function_info) { |
428 HandleScope scope; | 311 HandleScope scope; |
429 SetFirstTable(TablePut(source, context, function_info)); | 312 SetFirstTable(TablePut(source, context, function_info)); |
430 } | 313 } |
(...skipping 13 matching lines...) Expand all Loading... |
444 if (result->IsFixedArray()) { | 327 if (result->IsFixedArray()) { |
445 break; | 328 break; |
446 } | 329 } |
447 } | 330 } |
448 } | 331 } |
449 if (result->IsFixedArray()) { | 332 if (result->IsFixedArray()) { |
450 Handle<FixedArray> data(FixedArray::cast(result)); | 333 Handle<FixedArray> data(FixedArray::cast(result)); |
451 if (generation != 0) { | 334 if (generation != 0) { |
452 Put(source, flags, data); | 335 Put(source, flags, data); |
453 } | 336 } |
454 Counters::compilation_cache_hits.Increment(); | 337 COUNTERS->compilation_cache_hits()->Increment(); |
455 return data; | 338 return data; |
456 } else { | 339 } else { |
457 Counters::compilation_cache_misses.Increment(); | 340 COUNTERS->compilation_cache_misses()->Increment(); |
458 return Handle<FixedArray>::null(); | 341 return Handle<FixedArray>::null(); |
459 } | 342 } |
460 } | 343 } |
461 | 344 |
462 | 345 |
463 MaybeObject* CompilationCacheRegExp::TryTablePut( | 346 MaybeObject* CompilationCacheRegExp::TryTablePut( |
464 Handle<String> source, | 347 Handle<String> source, |
465 JSRegExp::Flags flags, | 348 JSRegExp::Flags flags, |
466 Handle<FixedArray> data) { | 349 Handle<FixedArray> data) { |
467 Handle<CompilationCacheTable> table = GetFirstTable(); | 350 Handle<CompilationCacheTable> table = GetFirstTable(); |
468 return table->PutRegExp(*source, flags, *data); | 351 return table->PutRegExp(*source, flags, *data); |
469 } | 352 } |
470 | 353 |
471 | 354 |
472 Handle<CompilationCacheTable> CompilationCacheRegExp::TablePut( | 355 Handle<CompilationCacheTable> CompilationCacheRegExp::TablePut( |
473 Handle<String> source, | 356 Handle<String> source, |
474 JSRegExp::Flags flags, | 357 JSRegExp::Flags flags, |
475 Handle<FixedArray> data) { | 358 Handle<FixedArray> data) { |
476 CALL_HEAP_FUNCTION(TryTablePut(source, flags, data), CompilationCacheTable); | 359 Isolate* isolate = Isolate::Current(); |
| 360 CALL_HEAP_FUNCTION(isolate, |
| 361 TryTablePut(source, flags, data), |
| 362 CompilationCacheTable); |
477 } | 363 } |
478 | 364 |
479 | 365 |
480 void CompilationCacheRegExp::Put(Handle<String> source, | 366 void CompilationCacheRegExp::Put(Handle<String> source, |
481 JSRegExp::Flags flags, | 367 JSRegExp::Flags flags, |
482 Handle<FixedArray> data) { | 368 Handle<FixedArray> data) { |
483 HandleScope scope; | 369 HandleScope scope; |
484 SetFirstTable(TablePut(source, flags, data)); | 370 SetFirstTable(TablePut(source, flags, data)); |
485 } | 371 } |
486 | 372 |
487 | 373 |
488 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { | 374 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { |
489 if (!IsEnabled()) return; | 375 if (!IsEnabled()) return; |
490 | 376 |
491 eval_global.Remove(function_info); | 377 eval_global_.Remove(function_info); |
492 eval_contextual.Remove(function_info); | 378 eval_contextual_.Remove(function_info); |
493 script.Remove(function_info); | 379 script_.Remove(function_info); |
494 } | 380 } |
495 | 381 |
496 | 382 |
497 Handle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source, | 383 Handle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source, |
498 Handle<Object> name, | 384 Handle<Object> name, |
499 int line_offset, | 385 int line_offset, |
500 int column_offset) { | 386 int column_offset) { |
501 if (!IsEnabled()) { | 387 if (!IsEnabled()) { |
502 return Handle<SharedFunctionInfo>::null(); | 388 return Handle<SharedFunctionInfo>::null(); |
503 } | 389 } |
504 | 390 |
505 return script.Lookup(source, name, line_offset, column_offset); | 391 return script_.Lookup(source, name, line_offset, column_offset); |
506 } | 392 } |
507 | 393 |
508 | 394 |
509 Handle<SharedFunctionInfo> CompilationCache::LookupEval( | 395 Handle<SharedFunctionInfo> CompilationCache::LookupEval( |
510 Handle<String> source, | 396 Handle<String> source, |
511 Handle<Context> context, | 397 Handle<Context> context, |
512 bool is_global, | 398 bool is_global, |
513 StrictModeFlag strict_mode) { | 399 StrictModeFlag strict_mode) { |
514 if (!IsEnabled()) { | 400 if (!IsEnabled()) { |
515 return Handle<SharedFunctionInfo>::null(); | 401 return Handle<SharedFunctionInfo>::null(); |
516 } | 402 } |
517 | 403 |
518 Handle<SharedFunctionInfo> result; | 404 Handle<SharedFunctionInfo> result; |
519 if (is_global) { | 405 if (is_global) { |
520 result = eval_global.Lookup(source, context, strict_mode); | 406 result = eval_global_.Lookup(source, context, strict_mode); |
521 } else { | 407 } else { |
522 result = eval_contextual.Lookup(source, context, strict_mode); | 408 result = eval_contextual_.Lookup(source, context, strict_mode); |
523 } | 409 } |
524 return result; | 410 return result; |
525 } | 411 } |
526 | 412 |
527 | 413 |
528 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, | 414 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, |
529 JSRegExp::Flags flags) { | 415 JSRegExp::Flags flags) { |
530 if (!IsEnabled()) { | 416 if (!IsEnabled()) { |
531 return Handle<FixedArray>::null(); | 417 return Handle<FixedArray>::null(); |
532 } | 418 } |
533 | 419 |
534 return reg_exp.Lookup(source, flags); | 420 return reg_exp_.Lookup(source, flags); |
535 } | 421 } |
536 | 422 |
537 | 423 |
538 void CompilationCache::PutScript(Handle<String> source, | 424 void CompilationCache::PutScript(Handle<String> source, |
539 Handle<SharedFunctionInfo> function_info) { | 425 Handle<SharedFunctionInfo> function_info) { |
540 if (!IsEnabled()) { | 426 if (!IsEnabled()) { |
541 return; | 427 return; |
542 } | 428 } |
543 | 429 |
544 script.Put(source, function_info); | 430 script_.Put(source, function_info); |
545 } | 431 } |
546 | 432 |
547 | 433 |
548 void CompilationCache::PutEval(Handle<String> source, | 434 void CompilationCache::PutEval(Handle<String> source, |
549 Handle<Context> context, | 435 Handle<Context> context, |
550 bool is_global, | 436 bool is_global, |
551 Handle<SharedFunctionInfo> function_info) { | 437 Handle<SharedFunctionInfo> function_info) { |
552 if (!IsEnabled()) { | 438 if (!IsEnabled()) { |
553 return; | 439 return; |
554 } | 440 } |
555 | 441 |
556 HandleScope scope; | 442 HandleScope scope; |
557 if (is_global) { | 443 if (is_global) { |
558 eval_global.Put(source, context, function_info); | 444 eval_global_.Put(source, context, function_info); |
559 } else { | 445 } else { |
560 eval_contextual.Put(source, context, function_info); | 446 eval_contextual_.Put(source, context, function_info); |
561 } | 447 } |
562 } | 448 } |
563 | 449 |
564 | 450 |
565 | 451 |
566 void CompilationCache::PutRegExp(Handle<String> source, | 452 void CompilationCache::PutRegExp(Handle<String> source, |
567 JSRegExp::Flags flags, | 453 JSRegExp::Flags flags, |
568 Handle<FixedArray> data) { | 454 Handle<FixedArray> data) { |
569 if (!IsEnabled()) { | 455 if (!IsEnabled()) { |
570 return; | 456 return; |
571 } | 457 } |
572 | 458 |
573 reg_exp.Put(source, flags, data); | 459 reg_exp_.Put(source, flags, data); |
574 } | 460 } |
575 | 461 |
576 | 462 |
577 static bool SourceHashCompare(void* key1, void* key2) { | 463 static bool SourceHashCompare(void* key1, void* key2) { |
578 return key1 == key2; | 464 return key1 == key2; |
579 } | 465 } |
580 | 466 |
581 | 467 |
582 static HashMap* EagerOptimizingSet() { | 468 HashMap* CompilationCache::EagerOptimizingSet() { |
583 static HashMap map(&SourceHashCompare); | 469 if (eager_optimizing_set_ == NULL) { |
584 return ↦ | 470 eager_optimizing_set_ = new HashMap(&SourceHashCompare); |
| 471 } |
| 472 return eager_optimizing_set_; |
585 } | 473 } |
586 | 474 |
587 | 475 |
588 bool CompilationCache::ShouldOptimizeEagerly(Handle<JSFunction> function) { | 476 bool CompilationCache::ShouldOptimizeEagerly(Handle<JSFunction> function) { |
589 if (FLAG_opt_eagerly) return true; | 477 if (FLAG_opt_eagerly) return true; |
590 uint32_t hash = function->SourceHash(); | 478 uint32_t hash = function->SourceHash(); |
591 void* key = reinterpret_cast<void*>(hash); | 479 void* key = reinterpret_cast<void*>(hash); |
592 return EagerOptimizingSet()->Lookup(key, hash, false) != NULL; | 480 return EagerOptimizingSet()->Lookup(key, hash, false) != NULL; |
593 } | 481 } |
594 | 482 |
(...skipping 13 matching lines...) Expand all Loading... |
608 | 496 |
609 | 497 |
610 void CompilationCache::ResetEagerOptimizingData() { | 498 void CompilationCache::ResetEagerOptimizingData() { |
611 HashMap* set = EagerOptimizingSet(); | 499 HashMap* set = EagerOptimizingSet(); |
612 if (set->occupancy() > 0) set->Clear(); | 500 if (set->occupancy() > 0) set->Clear(); |
613 } | 501 } |
614 | 502 |
615 | 503 |
616 void CompilationCache::Clear() { | 504 void CompilationCache::Clear() { |
617 for (int i = 0; i < kSubCacheCount; i++) { | 505 for (int i = 0; i < kSubCacheCount; i++) { |
618 subcaches[i]->Clear(); | 506 subcaches_[i]->Clear(); |
619 } | 507 } |
620 } | 508 } |
621 | 509 |
| 510 |
622 void CompilationCache::Iterate(ObjectVisitor* v) { | 511 void CompilationCache::Iterate(ObjectVisitor* v) { |
623 for (int i = 0; i < kSubCacheCount; i++) { | 512 for (int i = 0; i < kSubCacheCount; i++) { |
624 subcaches[i]->Iterate(v); | 513 subcaches_[i]->Iterate(v); |
625 } | 514 } |
626 } | 515 } |
627 | 516 |
628 | 517 |
629 void CompilationCache::IterateFunctions(ObjectVisitor* v) { | 518 void CompilationCache::IterateFunctions(ObjectVisitor* v) { |
630 for (int i = 0; i < kSubCacheCount; i++) { | 519 for (int i = 0; i < kSubCacheCount; i++) { |
631 subcaches[i]->IterateFunctions(v); | 520 subcaches_[i]->IterateFunctions(v); |
632 } | 521 } |
633 } | 522 } |
634 | 523 |
635 | 524 |
636 void CompilationCache::MarkCompactPrologue() { | 525 void CompilationCache::MarkCompactPrologue() { |
637 for (int i = 0; i < kSubCacheCount; i++) { | 526 for (int i = 0; i < kSubCacheCount; i++) { |
638 subcaches[i]->Age(); | 527 subcaches_[i]->Age(); |
639 } | 528 } |
640 } | 529 } |
641 | 530 |
642 | 531 |
643 void CompilationCache::Enable() { | 532 void CompilationCache::Enable() { |
644 enabled = true; | 533 enabled_ = true; |
645 } | 534 } |
646 | 535 |
647 | 536 |
648 void CompilationCache::Disable() { | 537 void CompilationCache::Disable() { |
649 enabled = false; | 538 enabled_ = false; |
650 Clear(); | 539 Clear(); |
651 } | 540 } |
652 | 541 |
653 | 542 |
654 } } // namespace v8::internal | 543 } } // namespace v8::internal |
OLD | NEW |