OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
8 #include "src/compilation-cache.h" | 8 #include "src/compilation-cache.h" |
9 #include "src/serialize.h" | 9 #include "src/serialize.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 | 14 |
15 // The number of generations for each sub cache. | 15 // The number of generations for each sub cache. |
16 // The number of ScriptGenerations is carefully chosen based on histograms. | |
17 // See issue 458: http://code.google.com/p/v8/issues/detail?id=458 | |
18 static const int kScriptGenerations = 5; | |
19 static const int kEvalGlobalGenerations = 2; | |
20 static const int kEvalContextualGenerations = 2; | |
21 static const int kRegExpGenerations = 2; | 16 static const int kRegExpGenerations = 2; |
22 | 17 |
23 // Initial size of each compilation cache table allocated. | 18 // Initial size of each compilation cache table allocated. |
24 static const int kInitialCacheSize = 64; | 19 static const int kInitialCacheSize = 64; |
25 | 20 |
26 | 21 |
27 CompilationCache::CompilationCache(Isolate* isolate) | 22 CompilationCache::CompilationCache(Isolate* isolate) |
28 : isolate_(isolate), | 23 : isolate_(isolate), |
29 script_(isolate, kScriptGenerations), | 24 script_(isolate, 1), |
30 eval_global_(isolate, kEvalGlobalGenerations), | 25 eval_global_(isolate, 1), |
31 eval_contextual_(isolate, kEvalContextualGenerations), | 26 eval_contextual_(isolate, 1), |
32 reg_exp_(isolate, kRegExpGenerations), | 27 reg_exp_(isolate, kRegExpGenerations), |
33 enabled_(true) { | 28 enabled_(true) { |
34 CompilationSubCache* subcaches[kSubCacheCount] = | 29 CompilationSubCache* subcaches[kSubCacheCount] = |
35 {&script_, &eval_global_, &eval_contextual_, ®_exp_}; | 30 {&script_, &eval_global_, &eval_contextual_, ®_exp_}; |
36 for (int i = 0; i < kSubCacheCount; ++i) { | 31 for (int i = 0; i < kSubCacheCount; ++i) { |
37 subcaches_[i] = subcaches[i]; | 32 subcaches_[i] = subcaches[i]; |
38 } | 33 } |
39 } | 34 } |
40 | 35 |
41 | 36 |
42 CompilationCache::~CompilationCache() {} | 37 CompilationCache::~CompilationCache() {} |
43 | 38 |
44 | 39 |
45 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { | 40 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { |
46 DCHECK(generation < generations_); | 41 DCHECK(generation < generations_); |
47 Handle<CompilationCacheTable> result; | 42 Handle<CompilationCacheTable> result; |
48 if (tables_[generation]->IsUndefined()) { | 43 if (tables_[generation]->IsUndefined()) { |
49 result = CompilationCacheTable::New(isolate(), kInitialCacheSize); | 44 result = CompilationCacheTable::New(isolate(), kInitialCacheSize); |
50 tables_[generation] = *result; | 45 tables_[generation] = *result; |
51 } else { | 46 } else { |
52 CompilationCacheTable* table = | 47 CompilationCacheTable* table = |
53 CompilationCacheTable::cast(tables_[generation]); | 48 CompilationCacheTable::cast(tables_[generation]); |
54 result = Handle<CompilationCacheTable>(table, isolate()); | 49 result = Handle<CompilationCacheTable>(table, isolate()); |
55 } | 50 } |
56 return result; | 51 return result; |
57 } | 52 } |
58 | 53 |
59 | 54 |
60 void CompilationSubCache::Age() { | 55 void CompilationSubCache::Age() { |
| 56 // Don't directly age single-generation caches. |
| 57 if (generations_ == 1) { |
| 58 if (tables_[0] != isolate()->heap()->undefined_value()) { |
| 59 CompilationCacheTable::cast(tables_[0])->Age(); |
| 60 } |
| 61 return; |
| 62 } |
| 63 |
61 // Age the generations implicitly killing off the oldest. | 64 // Age the generations implicitly killing off the oldest. |
62 for (int i = generations_ - 1; i > 0; i--) { | 65 for (int i = generations_ - 1; i > 0; i--) { |
63 tables_[i] = tables_[i - 1]; | 66 tables_[i] = tables_[i - 1]; |
64 } | 67 } |
65 | 68 |
66 // Set the first generation as unborn. | 69 // Set the first generation as unborn. |
67 tables_[0] = isolate()->heap()->undefined_value(); | 70 tables_[0] = isolate()->heap()->undefined_value(); |
68 } | 71 } |
69 | 72 |
70 | 73 |
(...skipping 24 matching lines...) Expand all Loading... |
95 for (int generation = 0; generation < generations(); generation++) { | 98 for (int generation = 0; generation < generations(); generation++) { |
96 Handle<CompilationCacheTable> table = GetTable(generation); | 99 Handle<CompilationCacheTable> table = GetTable(generation); |
97 table->Remove(*function_info); | 100 table->Remove(*function_info); |
98 } | 101 } |
99 } | 102 } |
100 } | 103 } |
101 | 104 |
102 | 105 |
103 CompilationCacheScript::CompilationCacheScript(Isolate* isolate, | 106 CompilationCacheScript::CompilationCacheScript(Isolate* isolate, |
104 int generations) | 107 int generations) |
105 : CompilationSubCache(isolate, generations), | 108 : CompilationSubCache(isolate, generations) {} |
106 script_histogram_(NULL), | |
107 script_histogram_initialized_(false) { } | |
108 | 109 |
109 | 110 |
110 // We only re-use a cached function for some script source code if the | 111 // We only re-use a cached function for some script source code if the |
111 // script originates from the same place. This is to avoid issues | 112 // script originates from the same place. This is to avoid issues |
112 // when reporting errors, etc. | 113 // when reporting errors, etc. |
113 bool CompilationCacheScript::HasOrigin( | 114 bool CompilationCacheScript::HasOrigin( |
114 Handle<SharedFunctionInfo> function_info, | 115 Handle<SharedFunctionInfo> function_info, |
115 Handle<Object> name, | 116 Handle<Object> name, |
116 int line_offset, | 117 int line_offset, |
117 int column_offset, | 118 int column_offset, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 line_offset, | 167 line_offset, |
167 column_offset, | 168 column_offset, |
168 is_shared_cross_origin)) { | 169 is_shared_cross_origin)) { |
169 result = *function_info; | 170 result = *function_info; |
170 break; | 171 break; |
171 } | 172 } |
172 } | 173 } |
173 } | 174 } |
174 } | 175 } |
175 | 176 |
176 if (!script_histogram_initialized_) { | |
177 script_histogram_ = isolate()->stats_table()->CreateHistogram( | |
178 "V8.ScriptCache", | |
179 0, | |
180 kScriptGenerations, | |
181 kScriptGenerations + 1); | |
182 script_histogram_initialized_ = true; | |
183 } | |
184 | |
185 if (script_histogram_ != NULL) { | |
186 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. | |
187 isolate()->stats_table()->AddHistogramSample(script_histogram_, generation); | |
188 } | |
189 | |
190 // Once outside the manacles of the handle scope, we need to recheck | 177 // Once outside the manacles of the handle scope, we need to recheck |
191 // to see if we actually found a cached script. If so, we return a | 178 // to see if we actually found a cached script. If so, we return a |
192 // handle created in the caller's handle scope. | 179 // handle created in the caller's handle scope. |
193 if (result != NULL) { | 180 if (result != NULL) { |
194 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result), | 181 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result), |
195 isolate()); | 182 isolate()); |
196 DCHECK(HasOrigin(shared, | 183 DCHECK(HasOrigin(shared, |
197 name, | 184 name, |
198 line_offset, | 185 line_offset, |
199 column_offset, | 186 column_offset, |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 405 } |
419 | 406 |
420 | 407 |
421 void CompilationCache::Disable() { | 408 void CompilationCache::Disable() { |
422 enabled_ = false; | 409 enabled_ = false; |
423 Clear(); | 410 Clear(); |
424 } | 411 } |
425 | 412 |
426 | 413 |
427 } } // namespace v8::internal | 414 } } // namespace v8::internal |
OLD | NEW |