blob: 7ace2f7db08a348b9168071ec796af60bb27bc73 [file] [log] [blame]
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orgb9123622008-09-17 14:05:56 +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
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +000030#include "assembler.h"
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000031#include "compilation-cache.h"
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000032#include "serialize.h"
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000033
kasperl@chromium.org71affb52009-05-26 05:44:31 +000034namespace v8 {
35namespace internal {
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000036
ager@chromium.org5aa501c2009-06-23 07:57:28 +000037
38// The number of generations for each sub cache.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +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
ager@chromium.org5aa501c2009-06-23 07:57:28 +000041static const int kScriptGenerations = 5;
42static const int kEvalGlobalGenerations = 2;
43static const int kEvalContextualGenerations = 2;
44static const int kRegExpGenerations = 2;
45
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000046// Initial size of each compilation cache table allocated.
ager@chromium.org5aa501c2009-06-23 07:57:28 +000047static const int kInitialCacheSize = 64;
48
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000049
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000050CompilationCache::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),
ricow@chromium.org4f693d62011-07-04 14:01:31 +000056 enabled_(true) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000057 CompilationSubCache* subcaches[kSubCacheCount] =
58 {&script_, &eval_global_, &eval_contextual_, &reg_exp_};
59 for (int i = 0; i < kSubCacheCount; ++i) {
60 subcaches_[i] = subcaches[i];
ager@chromium.org5aa501c2009-06-23 07:57:28 +000061 }
kasperl@chromium.org71affb52009-05-26 05:44:31 +000062}
63
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000064
ricow@chromium.org4f693d62011-07-04 14:01:31 +000065CompilationCache::~CompilationCache() {}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000066
67
68static Handle<CompilationCacheTable> AllocateTable(Isolate* isolate, int size) {
69 CALL_HEAP_FUNCTION(isolate,
ulan@chromium.org6e196bf2013-03-13 09:38:22 +000070 CompilationCacheTable::Allocate(isolate->heap(), size),
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000071 CompilationCacheTable);
72}
73
74
ager@chromium.org5aa501c2009-06-23 07:57:28 +000075Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
76 ASSERT(generation < generations_);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000077 Handle<CompilationCacheTable> result;
ager@chromium.org5aa501c2009-06-23 07:57:28 +000078 if (tables_[generation]->IsUndefined()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000079 result = AllocateTable(isolate(), kInitialCacheSize);
ager@chromium.org5aa501c2009-06-23 07:57:28 +000080 tables_[generation] = *result;
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000081 } else {
ager@chromium.org5aa501c2009-06-23 07:57:28 +000082 CompilationCacheTable* table =
83 CompilationCacheTable::cast(tables_[generation]);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000084 result = Handle<CompilationCacheTable>(table, isolate());
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000085 }
86 return result;
87}
88
ager@chromium.org5aa501c2009-06-23 07:57:28 +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];
ager@chromium.org381abbb2009-02-25 13:23:22 +000093 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +000094
95 // Set the first generation as unborn.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000096 tables_[0] = isolate()->heap()->undefined_value();
ager@chromium.org381abbb2009-02-25 13:23:22 +000097}
98
99
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000100void CompilationSubCache::IterateFunctions(ObjectVisitor* v) {
danno@chromium.org72204d52012-10-31 10:02:10 +0000101 Object* undefined = isolate()->heap()->undefined_value();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000102 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
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000110void CompilationSubCache::Iterate(ObjectVisitor* v) {
111 v->VisitPointers(&tables_[0], &tables_[generations_]);
112}
113
114
115void CompilationSubCache::Clear() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000116 MemsetPointer(tables_, isolate()->heap()->undefined_value(), generations_);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000117}
118
119
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120void 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.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000123 { HandleScope scope(isolate());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124 for (int generation = 0; generation < generations(); generation++) {
125 Handle<CompilationCacheTable> table = GetTable(generation);
126 table->Remove(*function_info);
127 }
128 }
129}
130
131
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000132CompilationCacheScript::CompilationCacheScript(Isolate* isolate,
133 int generations)
134 : CompilationSubCache(isolate, generations),
135 script_histogram_(NULL),
136 script_histogram_initialized_(false) { }
137
138
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +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.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000142bool CompilationCacheScript::HasOrigin(
143 Handle<SharedFunctionInfo> function_info,
144 Handle<Object> name,
145 int line_offset,
146 int column_offset) {
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000147 Handle<Script> script =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000148 Handle<Script>(Script::cast(function_info->script()), isolate());
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +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
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000164// 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.
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000168Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(
169 Handle<String> source,
170 Handle<Object> name,
171 int line_offset,
172 int column_offset,
173 Handle<Context> context) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000174 Object* result = NULL;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000175 int generation;
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000176
177 // Probe the script generation tables. Make sure not to leak handles
178 // into the caller's handle scope.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000179 { HandleScope scope(isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000180 for (generation = 0; generation < generations(); generation++) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000181 Handle<CompilationCacheTable> table = GetTable(generation);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000182 Handle<Object> probe(table->Lookup(*source, *context), isolate());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000183 if (probe->IsSharedFunctionInfo()) {
184 Handle<SharedFunctionInfo> function_info =
185 Handle<SharedFunctionInfo>::cast(probe);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000186 // Break when we've found a suitable shared function info that
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000187 // matches the origin.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000188 if (HasOrigin(function_info, name, line_offset, column_offset)) {
189 result = *function_info;
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000190 break;
191 }
192 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000193 }
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000194 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000195
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000196 if (!script_histogram_initialized_) {
197 script_histogram_ = isolate()->stats_table()->CreateHistogram(
198 "V8.ScriptCache",
199 0,
200 kScriptGenerations,
201 kScriptGenerations + 1);
202 script_histogram_initialized_ = true;
203 }
kasperl@chromium.org31ca8882009-05-26 09:36:02 +0000204
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000205 if (script_histogram_ != NULL) {
kasperl@chromium.org31ca8882009-05-26 09:36:02 +0000206 // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000207 isolate()->stats_table()->AddHistogramSample(script_histogram_, generation);
kasperl@chromium.org31ca8882009-05-26 09:36:02 +0000208 }
209
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000210 // Once outside the manacles of the handle scope, we need to recheck
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000211 // to see if we actually found a cached script. If so, we return a
212 // handle created in the caller's handle scope.
213 if (result != NULL) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000214 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result),
215 isolate());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000216 ASSERT(HasOrigin(shared, name, line_offset, column_offset));
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000217 // If the script was found in a later generation, we promote it to
218 // the first generation to let it survive longer in the cache.
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000219 if (generation != 0) Put(source, context, shared);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000220 isolate()->counters()->compilation_cache_hits()->Increment();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000221 return shared;
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000222 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000223 isolate()->counters()->compilation_cache_misses()->Increment();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000224 return Handle<SharedFunctionInfo>::null();
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000225 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000226}
227
228
lrn@chromium.org303ada72010-10-27 09:33:13 +0000229MaybeObject* CompilationCacheScript::TryTablePut(
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000230 Handle<String> source,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000231 Handle<Context> context,
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000232 Handle<SharedFunctionInfo> function_info) {
233 Handle<CompilationCacheTable> table = GetFirstTable();
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000234 return table->Put(*source, *context, *function_info);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000235}
236
237
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000238Handle<CompilationCacheTable> CompilationCacheScript::TablePut(
239 Handle<String> source,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000240 Handle<Context> context,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000241 Handle<SharedFunctionInfo> function_info) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000242 CALL_HEAP_FUNCTION(isolate(),
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000243 TryTablePut(source, context, function_info),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000244 CompilationCacheTable);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000245}
246
247
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000248void CompilationCacheScript::Put(Handle<String> source,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000249 Handle<Context> context,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000250 Handle<SharedFunctionInfo> function_info) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000251 HandleScope scope(isolate());
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000252 SetFirstTable(TablePut(source, context, function_info));
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000253}
254
255
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000256Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000257 Handle<String> source,
258 Handle<Context> context,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000259 LanguageMode language_mode,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000260 int scope_position) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000261 // Make sure not to leak the table into the surrounding handle
262 // scope. Otherwise, we risk keeping old tables around even after
263 // having cleared the cache.
264 Object* result = NULL;
265 int generation;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000266 { HandleScope scope(isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000267 for (generation = 0; generation < generations(); generation++) {
268 Handle<CompilationCacheTable> table = GetTable(generation);
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000269 result = table->LookupEval(
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000270 *source, *context, language_mode, scope_position);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000271 if (result->IsSharedFunctionInfo()) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000272 break;
273 }
274 }
275 }
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000276 if (result->IsSharedFunctionInfo()) {
277 Handle<SharedFunctionInfo>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000278 function_info(SharedFunctionInfo::cast(result), isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000279 if (generation != 0) {
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000280 Put(source, context, function_info, scope_position);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000281 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000282 isolate()->counters()->compilation_cache_hits()->Increment();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000283 return function_info;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000284 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000285 isolate()->counters()->compilation_cache_misses()->Increment();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000286 return Handle<SharedFunctionInfo>::null();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000287 }
288}
289
290
lrn@chromium.org303ada72010-10-27 09:33:13 +0000291MaybeObject* CompilationCacheEval::TryTablePut(
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000292 Handle<String> source,
293 Handle<Context> context,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000294 Handle<SharedFunctionInfo> function_info,
295 int scope_position) {
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000296 Handle<CompilationCacheTable> table = GetFirstTable();
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000297 return table->PutEval(*source, *context, *function_info, scope_position);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000298}
299
300
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000301Handle<CompilationCacheTable> CompilationCacheEval::TablePut(
302 Handle<String> source,
303 Handle<Context> context,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000304 Handle<SharedFunctionInfo> function_info,
305 int scope_position) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000306 CALL_HEAP_FUNCTION(isolate(),
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000307 TryTablePut(
308 source, context, function_info, scope_position),
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000309 CompilationCacheTable);
310}
311
312
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000313void CompilationCacheEval::Put(Handle<String> source,
314 Handle<Context> context,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000315 Handle<SharedFunctionInfo> function_info,
316 int scope_position) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000317 HandleScope scope(isolate());
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000318 SetFirstTable(TablePut(source, context, function_info, scope_position));
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000319}
320
321
322Handle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
323 JSRegExp::Flags flags) {
324 // Make sure not to leak the table into the surrounding handle
325 // scope. Otherwise, we risk keeping old tables around even after
326 // having cleared the cache.
327 Object* result = NULL;
328 int generation;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000329 { HandleScope scope(isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000330 for (generation = 0; generation < generations(); generation++) {
331 Handle<CompilationCacheTable> table = GetTable(generation);
332 result = table->LookupRegExp(*source, flags);
333 if (result->IsFixedArray()) {
334 break;
335 }
336 }
337 }
338 if (result->IsFixedArray()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000339 Handle<FixedArray> data(FixedArray::cast(result), isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000340 if (generation != 0) {
341 Put(source, flags, data);
342 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000343 isolate()->counters()->compilation_cache_hits()->Increment();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000344 return data;
345 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000346 isolate()->counters()->compilation_cache_misses()->Increment();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000347 return Handle<FixedArray>::null();
348 }
349}
350
351
lrn@chromium.org303ada72010-10-27 09:33:13 +0000352MaybeObject* CompilationCacheRegExp::TryTablePut(
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000353 Handle<String> source,
354 JSRegExp::Flags flags,
355 Handle<FixedArray> data) {
356 Handle<CompilationCacheTable> table = GetFirstTable();
357 return table->PutRegExp(*source, flags, *data);
358}
359
360
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000361Handle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
362 Handle<String> source,
363 JSRegExp::Flags flags,
364 Handle<FixedArray> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000365 CALL_HEAP_FUNCTION(isolate(),
366 TryTablePut(source, flags, data),
367 CompilationCacheTable);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000368}
369
370
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000371void CompilationCacheRegExp::Put(Handle<String> source,
372 JSRegExp::Flags flags,
373 Handle<FixedArray> data) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000374 HandleScope scope(isolate());
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000375 SetFirstTable(TablePut(source, flags, data));
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000376}
377
378
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000379void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
380 if (!IsEnabled()) return;
381
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000382 eval_global_.Remove(function_info);
383 eval_contextual_.Remove(function_info);
384 script_.Remove(function_info);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000385}
386
387
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000388Handle<SharedFunctionInfo> CompilationCache::LookupScript(
389 Handle<String> source,
390 Handle<Object> name,
391 int line_offset,
392 int column_offset,
393 Handle<Context> context) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000394 if (!IsEnabled()) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000395 return Handle<SharedFunctionInfo>::null();
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000396 }
397
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000398 return script_.Lookup(source, name, line_offset, column_offset, context);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000399}
400
401
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000402Handle<SharedFunctionInfo> CompilationCache::LookupEval(
403 Handle<String> source,
404 Handle<Context> context,
405 bool is_global,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000406 LanguageMode language_mode,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000407 int scope_position) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000408 if (!IsEnabled()) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000409 return Handle<SharedFunctionInfo>::null();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000410 }
411
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000412 Handle<SharedFunctionInfo> result;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000413 if (is_global) {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000414 result = eval_global_.Lookup(
415 source, context, language_mode, scope_position);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000416 } else {
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000417 ASSERT(scope_position != RelocInfo::kNoPosition);
418 result = eval_contextual_.Lookup(
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000419 source, context, language_mode, scope_position);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000420 }
421 return result;
422}
423
424
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000425Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
426 JSRegExp::Flags flags) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000427 if (!IsEnabled()) {
428 return Handle<FixedArray>::null();
429 }
430
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000431 return reg_exp_.Lookup(source, flags);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000432}
433
434
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000435void CompilationCache::PutScript(Handle<String> source,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000436 Handle<Context> context,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000437 Handle<SharedFunctionInfo> function_info) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000438 if (!IsEnabled()) {
439 return;
440 }
441
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000442 script_.Put(source, context, function_info);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000443}
444
445
446void CompilationCache::PutEval(Handle<String> source,
447 Handle<Context> context,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000448 bool is_global,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000449 Handle<SharedFunctionInfo> function_info,
450 int scope_position) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000451 if (!IsEnabled()) {
452 return;
453 }
454
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000455 HandleScope scope(isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000456 if (is_global) {
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000457 eval_global_.Put(source, context, function_info, scope_position);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000458 } else {
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000459 ASSERT(scope_position != RelocInfo::kNoPosition);
460 eval_contextual_.Put(source, context, function_info, scope_position);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000461 }
ager@chromium.org381abbb2009-02-25 13:23:22 +0000462}
463
464
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000465
466void CompilationCache::PutRegExp(Handle<String> source,
467 JSRegExp::Flags flags,
468 Handle<FixedArray> data) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000469 if (!IsEnabled()) {
470 return;
471 }
472
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000473 reg_exp_.Put(source, flags, data);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000474}
475
476
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000477void CompilationCache::Clear() {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000478 for (int i = 0; i < kSubCacheCount; i++) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000479 subcaches_[i]->Clear();
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000480 }
481}
482
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000483
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000484void CompilationCache::Iterate(ObjectVisitor* v) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000485 for (int i = 0; i < kSubCacheCount; i++) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000486 subcaches_[i]->Iterate(v);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000487 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000488}
489
490
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000491void CompilationCache::IterateFunctions(ObjectVisitor* v) {
492 for (int i = 0; i < kSubCacheCount; i++) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000493 subcaches_[i]->IterateFunctions(v);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000494 }
495}
496
497
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000498void CompilationCache::MarkCompactPrologue() {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000499 for (int i = 0; i < kSubCacheCount; i++) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000500 subcaches_[i]->Age();
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000501 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000502}
503
504
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000505void CompilationCache::Enable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000506 enabled_ = true;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000507}
508
509
510void CompilationCache::Disable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000511 enabled_ = false;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000512 Clear();
513}
514
515
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000516} } // namespace v8::internal