blob: 82cc2231a36326a38191a95cf2c80fea3112fbff [file] [log] [blame]
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27
28#include "v8.h"
29
Ben Murdoch592a9fc2012-03-05 11:04:45 +000030#include "assembler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000031#include "compilation-cache.h"
Andrei Popescu31002712010-02-23 13:46:05 +000032#include "serialize.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000033
34namespace v8 {
35namespace internal {
36
Steve Blocka7e24c12009-10-30 11:49:00 +000037
38// The number of generations for each sub cache.
Steve Block3ce2e202009-11-05 08:53:23 +000039// The number of ScriptGenerations is carefully chosen based on histograms.
40// See issue 458: http://code.google.com/p/v8/issues/detail?id=458
Steve Blocka7e24c12009-10-30 11:49:00 +000041static const int kScriptGenerations = 5;
42static const int kEvalGlobalGenerations = 2;
43static const int kEvalContextualGenerations = 2;
44static const int kRegExpGenerations = 2;
Steve Blocka7e24c12009-10-30 11:49:00 +000045
Steve Block3ce2e202009-11-05 08:53:23 +000046// Initial size of each compilation cache table allocated.
Steve Blocka7e24c12009-10-30 11:49:00 +000047static const int kInitialCacheSize = 64;
48
Steve Block6ded16b2010-05-10 14:33:55 +010049
Steve Block44f0eee2011-05-26 01:26:41 +010050CompilationCache::CompilationCache(Isolate* isolate)
51 : isolate_(isolate),
52 script_(isolate, kScriptGenerations),
53 eval_global_(isolate, kEvalGlobalGenerations),
54 eval_contextual_(isolate, kEvalContextualGenerations),
55 reg_exp_(isolate, kRegExpGenerations),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000056 enabled_(true) {
Steve Block44f0eee2011-05-26 01:26:41 +010057 CompilationSubCache* subcaches[kSubCacheCount] =
58 {&script_, &eval_global_, &eval_contextual_, &reg_exp_};
59 for (int i = 0; i < kSubCacheCount; ++i) {
60 subcaches_[i] = subcaches[i];
Steve Blocka7e24c12009-10-30 11:49:00 +000061 }
Steve Blocka7e24c12009-10-30 11:49:00 +000062}
63
64
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000065CompilationCache::~CompilationCache() {}
Steve Block44f0eee2011-05-26 01:26:41 +010066
67
68static Handle<CompilationCacheTable> AllocateTable(Isolate* isolate, int size) {
69 CALL_HEAP_FUNCTION(isolate,
70 CompilationCacheTable::Allocate(size),
Steve Blocka7e24c12009-10-30 11:49:00 +000071 CompilationCacheTable);
72}
73
74
75Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
76 ASSERT(generation < generations_);
77 Handle<CompilationCacheTable> result;
78 if (tables_[generation]->IsUndefined()) {
Steve Block44f0eee2011-05-26 01:26:41 +010079 result = AllocateTable(isolate(), kInitialCacheSize);
Steve Blocka7e24c12009-10-30 11:49:00 +000080 tables_[generation] = *result;
81 } else {
82 CompilationCacheTable* table =
83 CompilationCacheTable::cast(tables_[generation]);
Steve Block44f0eee2011-05-26 01:26:41 +010084 result = Handle<CompilationCacheTable>(table, isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +000085 }
86 return result;
87}
88
Steve Blocka7e24c12009-10-30 11:49:00 +000089void CompilationSubCache::Age() {
90 // Age the generations implicitly killing off the oldest.
91 for (int i = generations_ - 1; i > 0; i--) {
92 tables_[i] = tables_[i - 1];
93 }
94
95 // Set the first generation as unborn.
Steve Block44f0eee2011-05-26 01:26:41 +010096 tables_[0] = isolate()->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +000097}
98
99
Iain Merrick75681382010-08-19 15:07:18 +0100100void CompilationSubCache::IterateFunctions(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100101 Object* undefined = isolate()->heap()->raw_unchecked_undefined_value();
Iain Merrick75681382010-08-19 15:07:18 +0100102 for (int i = 0; i < generations_; i++) {
103 if (tables_[i] != undefined) {
104 reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v);
105 }
106 }
107}
108
109
Steve Blocka7e24c12009-10-30 11:49:00 +0000110void CompilationSubCache::Iterate(ObjectVisitor* v) {
111 v->VisitPointers(&tables_[0], &tables_[generations_]);
112}
113
114
115void CompilationSubCache::Clear() {
Steve Block44f0eee2011-05-26 01:26:41 +0100116 MemsetPointer(tables_, isolate()->heap()->undefined_value(), generations_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000117}
118
119
Ben Murdochb0fe1622011-05-05 13:52:32 +0100120void CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) {
121 // Probe the script generation tables. Make sure not to leak handles
122 // into the caller's handle scope.
Steve Block44f0eee2011-05-26 01:26:41 +0100123 { HandleScope scope(isolate());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100124 for (int generation = 0; generation < generations(); generation++) {
125 Handle<CompilationCacheTable> table = GetTable(generation);
126 table->Remove(*function_info);
127 }
128 }
129}
130
131
Steve Block44f0eee2011-05-26 01:26:41 +0100132CompilationCacheScript::CompilationCacheScript(Isolate* isolate,
133 int generations)
134 : CompilationSubCache(isolate, generations),
135 script_histogram_(NULL),
136 script_histogram_initialized_(false) { }
137
138
Steve Blocka7e24c12009-10-30 11:49:00 +0000139// We only re-use a cached function for some script source code if the
140// script originates from the same place. This is to avoid issues
141// when reporting errors, etc.
Steve Block6ded16b2010-05-10 14:33:55 +0100142bool CompilationCacheScript::HasOrigin(
143 Handle<SharedFunctionInfo> function_info,
144 Handle<Object> name,
145 int line_offset,
146 int column_offset) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 Handle<Script> script =
Steve Block44f0eee2011-05-26 01:26:41 +0100148 Handle<Script>(Script::cast(function_info->script()), isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000149 // If the script name isn't set, the boilerplate script should have
150 // an undefined name to have the same origin.
151 if (name.is_null()) {
152 return script->name()->IsUndefined();
153 }
154 // Do the fast bailout checks first.
155 if (line_offset != script->line_offset()->value()) return false;
156 if (column_offset != script->column_offset()->value()) return false;
157 // Check that both names are strings. If not, no match.
158 if (!name->IsString() || !script->name()->IsString()) return false;
159 // Compare the two name strings for equality.
160 return String::cast(*name)->Equals(String::cast(script->name()));
161}
162
163
164// TODO(245): Need to allow identical code from different contexts to
165// be cached in the same script generation. Currently the first use
166// will be cached, but subsequent code from different source / line
167// won't.
Steve Block6ded16b2010-05-10 14:33:55 +0100168Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
169 Handle<Object> name,
170 int line_offset,
171 int column_offset) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000172 Object* result = NULL;
173 int generation;
174
175 // Probe the script generation tables. Make sure not to leak handles
176 // into the caller's handle scope.
Steve Block44f0eee2011-05-26 01:26:41 +0100177 { HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000178 for (generation = 0; generation < generations(); generation++) {
179 Handle<CompilationCacheTable> table = GetTable(generation);
Steve Block44f0eee2011-05-26 01:26:41 +0100180 Handle<Object> probe(table->Lookup(*source), isolate());
Steve Block6ded16b2010-05-10 14:33:55 +0100181 if (probe->IsSharedFunctionInfo()) {
182 Handle<SharedFunctionInfo> function_info =
183 Handle<SharedFunctionInfo>::cast(probe);
184 // Break when we've found a suitable shared function info that
Steve Blocka7e24c12009-10-30 11:49:00 +0000185 // matches the origin.
Steve Block6ded16b2010-05-10 14:33:55 +0100186 if (HasOrigin(function_info, name, line_offset, column_offset)) {
187 result = *function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +0000188 break;
189 }
190 }
191 }
192 }
193
Steve Block44f0eee2011-05-26 01:26:41 +0100194 if (!script_histogram_initialized_) {
195 script_histogram_ = isolate()->stats_table()->CreateHistogram(
196 "V8.ScriptCache",
197 0,
198 kScriptGenerations,
199 kScriptGenerations + 1);
200 script_histogram_initialized_ = true;
201 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000202
Steve Block44f0eee2011-05-26 01:26:41 +0100203 if (script_histogram_ != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000204 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
Steve Block44f0eee2011-05-26 01:26:41 +0100205 isolate()->stats_table()->AddHistogramSample(script_histogram_, generation);
Steve Blocka7e24c12009-10-30 11:49:00 +0000206 }
207
208 // Once outside the manacles of the handle scope, we need to recheck
209 // to see if we actually found a cached script. If so, we return a
210 // handle created in the caller's handle scope.
211 if (result != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +0100212 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result),
213 isolate());
Steve Block6ded16b2010-05-10 14:33:55 +0100214 ASSERT(HasOrigin(shared, name, line_offset, column_offset));
Steve Blocka7e24c12009-10-30 11:49:00 +0000215 // If the script was found in a later generation, we promote it to
216 // the first generation to let it survive longer in the cache.
Steve Block6ded16b2010-05-10 14:33:55 +0100217 if (generation != 0) Put(source, shared);
Steve Block44f0eee2011-05-26 01:26:41 +0100218 isolate()->counters()->compilation_cache_hits()->Increment();
Steve Block6ded16b2010-05-10 14:33:55 +0100219 return shared;
Steve Blocka7e24c12009-10-30 11:49:00 +0000220 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100221 isolate()->counters()->compilation_cache_misses()->Increment();
Steve Block6ded16b2010-05-10 14:33:55 +0100222 return Handle<SharedFunctionInfo>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +0000223 }
224}
225
226
John Reck59135872010-11-02 12:39:01 -0700227MaybeObject* CompilationCacheScript::TryTablePut(
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100228 Handle<String> source,
229 Handle<SharedFunctionInfo> function_info) {
230 Handle<CompilationCacheTable> table = GetFirstTable();
231 return table->Put(*source, *function_info);
232}
233
234
Steve Block6ded16b2010-05-10 14:33:55 +0100235Handle<CompilationCacheTable> CompilationCacheScript::TablePut(
236 Handle<String> source,
237 Handle<SharedFunctionInfo> function_info) {
Steve Block44f0eee2011-05-26 01:26:41 +0100238 CALL_HEAP_FUNCTION(isolate(),
239 TryTablePut(source, function_info),
240 CompilationCacheTable);
Steve Blocka7e24c12009-10-30 11:49:00 +0000241}
242
243
Steve Block6ded16b2010-05-10 14:33:55 +0100244void CompilationCacheScript::Put(Handle<String> source,
245 Handle<SharedFunctionInfo> function_info) {
Steve Block44f0eee2011-05-26 01:26:41 +0100246 HandleScope scope(isolate());
Steve Block6ded16b2010-05-10 14:33:55 +0100247 SetFirstTable(TablePut(source, function_info));
248}
249
250
251Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
Steve Block1e0659c2011-05-24 12:43:12 +0100252 Handle<String> source,
253 Handle<Context> context,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000254 LanguageMode language_mode,
255 int scope_position) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000256 // Make sure not to leak the table into the surrounding handle
257 // scope. Otherwise, we risk keeping old tables around even after
258 // having cleared the cache.
259 Object* result = NULL;
260 int generation;
Steve Block44f0eee2011-05-26 01:26:41 +0100261 { HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 for (generation = 0; generation < generations(); generation++) {
263 Handle<CompilationCacheTable> table = GetTable(generation);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000264 result = table->LookupEval(
265 *source, *context, language_mode, scope_position);
Steve Block6ded16b2010-05-10 14:33:55 +0100266 if (result->IsSharedFunctionInfo()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000267 break;
268 }
269 }
270 }
Steve Block6ded16b2010-05-10 14:33:55 +0100271 if (result->IsSharedFunctionInfo()) {
272 Handle<SharedFunctionInfo>
Steve Block44f0eee2011-05-26 01:26:41 +0100273 function_info(SharedFunctionInfo::cast(result), isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000274 if (generation != 0) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000275 Put(source, context, function_info, scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000276 }
Steve Block44f0eee2011-05-26 01:26:41 +0100277 isolate()->counters()->compilation_cache_hits()->Increment();
Steve Block6ded16b2010-05-10 14:33:55 +0100278 return function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +0000279 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100280 isolate()->counters()->compilation_cache_misses()->Increment();
Steve Block6ded16b2010-05-10 14:33:55 +0100281 return Handle<SharedFunctionInfo>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +0000282 }
283}
284
285
John Reck59135872010-11-02 12:39:01 -0700286MaybeObject* CompilationCacheEval::TryTablePut(
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100287 Handle<String> source,
288 Handle<Context> context,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000289 Handle<SharedFunctionInfo> function_info,
290 int scope_position) {
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100291 Handle<CompilationCacheTable> table = GetFirstTable();
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000292 return table->PutEval(*source, *context, *function_info, scope_position);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100293}
294
295
Steve Block6ded16b2010-05-10 14:33:55 +0100296Handle<CompilationCacheTable> CompilationCacheEval::TablePut(
297 Handle<String> source,
298 Handle<Context> context,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000299 Handle<SharedFunctionInfo> function_info,
300 int scope_position) {
Steve Block44f0eee2011-05-26 01:26:41 +0100301 CALL_HEAP_FUNCTION(isolate(),
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000302 TryTablePut(
303 source, context, function_info, scope_position),
Steve Block6ded16b2010-05-10 14:33:55 +0100304 CompilationCacheTable);
305}
306
307
Steve Blocka7e24c12009-10-30 11:49:00 +0000308void CompilationCacheEval::Put(Handle<String> source,
309 Handle<Context> context,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000310 Handle<SharedFunctionInfo> function_info,
311 int scope_position) {
Steve Block44f0eee2011-05-26 01:26:41 +0100312 HandleScope scope(isolate());
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000313 SetFirstTable(TablePut(source, context, function_info, scope_position));
Steve Blocka7e24c12009-10-30 11:49:00 +0000314}
315
316
317Handle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
318 JSRegExp::Flags flags) {
319 // Make sure not to leak the table into the surrounding handle
320 // scope. Otherwise, we risk keeping old tables around even after
321 // having cleared the cache.
322 Object* result = NULL;
323 int generation;
Steve Block44f0eee2011-05-26 01:26:41 +0100324 { HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000325 for (generation = 0; generation < generations(); generation++) {
326 Handle<CompilationCacheTable> table = GetTable(generation);
327 result = table->LookupRegExp(*source, flags);
328 if (result->IsFixedArray()) {
329 break;
330 }
331 }
332 }
333 if (result->IsFixedArray()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100334 Handle<FixedArray> data(FixedArray::cast(result), isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000335 if (generation != 0) {
336 Put(source, flags, data);
337 }
Steve Block44f0eee2011-05-26 01:26:41 +0100338 isolate()->counters()->compilation_cache_hits()->Increment();
Steve Blocka7e24c12009-10-30 11:49:00 +0000339 return data;
340 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100341 isolate()->counters()->compilation_cache_misses()->Increment();
Steve Blocka7e24c12009-10-30 11:49:00 +0000342 return Handle<FixedArray>::null();
343 }
344}
345
346
John Reck59135872010-11-02 12:39:01 -0700347MaybeObject* CompilationCacheRegExp::TryTablePut(
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100348 Handle<String> source,
349 JSRegExp::Flags flags,
350 Handle<FixedArray> data) {
351 Handle<CompilationCacheTable> table = GetFirstTable();
352 return table->PutRegExp(*source, flags, *data);
353}
354
355
Steve Block6ded16b2010-05-10 14:33:55 +0100356Handle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
357 Handle<String> source,
358 JSRegExp::Flags flags,
359 Handle<FixedArray> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100360 CALL_HEAP_FUNCTION(isolate(),
361 TryTablePut(source, flags, data),
362 CompilationCacheTable);
Steve Block6ded16b2010-05-10 14:33:55 +0100363}
364
365
Steve Blocka7e24c12009-10-30 11:49:00 +0000366void CompilationCacheRegExp::Put(Handle<String> source,
367 JSRegExp::Flags flags,
368 Handle<FixedArray> data) {
Steve Block44f0eee2011-05-26 01:26:41 +0100369 HandleScope scope(isolate());
Steve Block6ded16b2010-05-10 14:33:55 +0100370 SetFirstTable(TablePut(source, flags, data));
Steve Blocka7e24c12009-10-30 11:49:00 +0000371}
372
373
Ben Murdochb0fe1622011-05-05 13:52:32 +0100374void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
375 if (!IsEnabled()) return;
376
Steve Block44f0eee2011-05-26 01:26:41 +0100377 eval_global_.Remove(function_info);
378 eval_contextual_.Remove(function_info);
379 script_.Remove(function_info);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100380}
381
382
Steve Block6ded16b2010-05-10 14:33:55 +0100383Handle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source,
384 Handle<Object> name,
385 int line_offset,
386 int column_offset) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000387 if (!IsEnabled()) {
Steve Block6ded16b2010-05-10 14:33:55 +0100388 return Handle<SharedFunctionInfo>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +0000389 }
390
Steve Block44f0eee2011-05-26 01:26:41 +0100391 return script_.Lookup(source, name, line_offset, column_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +0000392}
393
394
Steve Block1e0659c2011-05-24 12:43:12 +0100395Handle<SharedFunctionInfo> CompilationCache::LookupEval(
396 Handle<String> source,
397 Handle<Context> context,
398 bool is_global,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000399 LanguageMode language_mode,
400 int scope_position) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000401 if (!IsEnabled()) {
Steve Block6ded16b2010-05-10 14:33:55 +0100402 return Handle<SharedFunctionInfo>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +0000403 }
404
Steve Block6ded16b2010-05-10 14:33:55 +0100405 Handle<SharedFunctionInfo> result;
Steve Blocka7e24c12009-10-30 11:49:00 +0000406 if (is_global) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000407 result = eval_global_.Lookup(
408 source, context, language_mode, scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000409 } else {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000410 ASSERT(scope_position != RelocInfo::kNoPosition);
411 result = eval_contextual_.Lookup(
412 source, context, language_mode, scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000413 }
414 return result;
415}
416
417
418Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
419 JSRegExp::Flags flags) {
420 if (!IsEnabled()) {
421 return Handle<FixedArray>::null();
422 }
423
Steve Block44f0eee2011-05-26 01:26:41 +0100424 return reg_exp_.Lookup(source, flags);
Steve Blocka7e24c12009-10-30 11:49:00 +0000425}
426
427
428void CompilationCache::PutScript(Handle<String> source,
Steve Block6ded16b2010-05-10 14:33:55 +0100429 Handle<SharedFunctionInfo> function_info) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000430 if (!IsEnabled()) {
431 return;
432 }
433
Steve Block44f0eee2011-05-26 01:26:41 +0100434 script_.Put(source, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000435}
436
437
438void CompilationCache::PutEval(Handle<String> source,
439 Handle<Context> context,
440 bool is_global,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000441 Handle<SharedFunctionInfo> function_info,
442 int scope_position) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000443 if (!IsEnabled()) {
444 return;
445 }
446
Steve Block44f0eee2011-05-26 01:26:41 +0100447 HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000448 if (is_global) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000449 eval_global_.Put(source, context, function_info, scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000450 } else {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000451 ASSERT(scope_position != RelocInfo::kNoPosition);
452 eval_contextual_.Put(source, context, function_info, scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000453 }
454}
455
456
457
458void CompilationCache::PutRegExp(Handle<String> source,
459 JSRegExp::Flags flags,
460 Handle<FixedArray> data) {
461 if (!IsEnabled()) {
462 return;
463 }
464
Steve Block44f0eee2011-05-26 01:26:41 +0100465 reg_exp_.Put(source, flags, data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000466}
467
468
469void CompilationCache::Clear() {
470 for (int i = 0; i < kSubCacheCount; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100471 subcaches_[i]->Clear();
Steve Blocka7e24c12009-10-30 11:49:00 +0000472 }
473}
474
Steve Block44f0eee2011-05-26 01:26:41 +0100475
Steve Blocka7e24c12009-10-30 11:49:00 +0000476void CompilationCache::Iterate(ObjectVisitor* v) {
477 for (int i = 0; i < kSubCacheCount; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100478 subcaches_[i]->Iterate(v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000479 }
480}
481
482
Iain Merrick75681382010-08-19 15:07:18 +0100483void CompilationCache::IterateFunctions(ObjectVisitor* v) {
484 for (int i = 0; i < kSubCacheCount; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100485 subcaches_[i]->IterateFunctions(v);
Iain Merrick75681382010-08-19 15:07:18 +0100486 }
487}
488
489
Steve Blocka7e24c12009-10-30 11:49:00 +0000490void CompilationCache::MarkCompactPrologue() {
491 for (int i = 0; i < kSubCacheCount; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100492 subcaches_[i]->Age();
Steve Blocka7e24c12009-10-30 11:49:00 +0000493 }
494}
495
496
497void CompilationCache::Enable() {
Steve Block44f0eee2011-05-26 01:26:41 +0100498 enabled_ = true;
Steve Blocka7e24c12009-10-30 11:49:00 +0000499}
500
501
502void CompilationCache::Disable() {
Steve Block44f0eee2011-05-26 01:26:41 +0100503 enabled_ = false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000504 Clear();
505}
506
507
508} } // namespace v8::internal