compilation-cache.cc revision 6ded16be15dd865a9b21ea304d5273c8be299c87
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h"
313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "serialize.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The number of sub caches covering the different types to cache.
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kSubCacheCount = 4;
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The number of generations for each sub cache.
403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The number of ScriptGenerations is carefully chosen based on histograms.
413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// See issue 458: http://code.google.com/p/v8/issues/detail?id=458
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kScriptGenerations = 5;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalGlobalGenerations = 2;
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalContextualGenerations = 2;
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kRegExpGenerations = 2;
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Initial size of each compilation cache table allocated.
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kInitialCacheSize = 64;
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Index for the first generation in the cache.
516ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic const int kFirstGeneration = 0;
526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The compilation cache consists of several generational sub-caches which uses
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this class as a base class. A sub-cache contains a compilation cache tables
553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// for each generation of the sub-cache. Since the same source code string has
563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// different compiled code for scripts and evals, we use separate sub-caches
573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// for different compilation modes, to avoid retrieving the wrong result.
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationSubCache {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationSubCache(int generations): generations_(generations) {
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_ = NewArray<Object*>(generations);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~CompilationSubCache() { DeleteArray(tables_); }
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the compilation cache tables for a specific generation.
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<CompilationCacheTable> GetTable(int generation);
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Accessors for first generation.
706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> GetFirstTable() {
716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return GetTable(kFirstGeneration);
726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void SetFirstTable(Handle<CompilationCacheTable> value) {
746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(kFirstGeneration < generations_);
756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    tables_[kFirstGeneration] = *value;
766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Age the sub-cache by evicting the oldest generation and creating a new
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // young generation.
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Age();
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GC support.
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Iterate(ObjectVisitor* v);
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear this sub-cache evicting all its content.
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Clear();
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Number of generations in this sub-cache.
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int generations() { return generations_; }
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generations_;  // Number of generations.
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object** tables_;  // Compilation cache tables - one for each generation.
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for scripts.
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheScript : public CompilationSubCache {
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationCacheScript(int generations)
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : CompilationSubCache(generations) { }
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> Lookup(Handle<String> source,
1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    Handle<Object> name,
1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    int line_offset,
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    int column_offset);
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info);
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Note: Returns a new hash table if operation results in expansion.
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> TablePut(
1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<String> source, Handle<SharedFunctionInfo> function_info);
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool HasOrigin(Handle<SharedFunctionInfo> function_info,
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 Handle<Object> name,
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 int line_offset,
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 int column_offset);
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for eval scripts.
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheEval: public CompilationSubCache {
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationCacheEval(int generations)
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : CompilationSubCache(generations) { }
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> Lookup(Handle<String> source,
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    Handle<Context> context);
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Put(Handle<String> source,
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Handle<Context> context,
1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block           Handle<SharedFunctionInfo> function_info);
1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Note: Returns a new hash table if operation results in expansion.
1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> TablePut(
1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<String> source,
1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<Context> context,
1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<SharedFunctionInfo> function_info);
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for regular expressions.
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheRegExp: public CompilationSubCache {
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationCacheRegExp(int generations)
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : CompilationSubCache(generations) { }
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Put(Handle<String> source,
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           JSRegExp::Flags flags,
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Handle<FixedArray> data);
1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Note: Returns a new hash table if operation results in expansion.
1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> TablePut(Handle<String> source,
1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         JSRegExp::Flags flags,
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<FixedArray> data);
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Statically allocate all the sub-caches.
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheScript script(kScriptGenerations);
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_global(kEvalGlobalGenerations);
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_contextual(kEvalContextualGenerations);
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheRegExp reg_exp(kRegExpGenerations);
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationSubCache* subcaches[kSubCacheCount] =
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {&script, &eval_global, &eval_contextual, &reg_exp};
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Current enable state of the compilation cache.
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool enabled = true;
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool IsEnabled() {
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return FLAG_compilation_cache && enabled;
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<CompilationCacheTable> AllocateTable(int size) {
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     CompilationCacheTable);
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(generation < generations_);
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<CompilationCacheTable> result;
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (tables_[generation]->IsUndefined()) {
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = AllocateTable(kInitialCacheSize);
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[generation] = *result;
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CompilationCacheTable* table =
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        CompilationCacheTable::cast(tables_[generation]);
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = Handle<CompilationCacheTable>(table);
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Age() {
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Age the generations implicitly killing off the oldest.
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = generations_ - 1; i > 0; i--) {
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[i] = tables_[i - 1];
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the first generation as unborn.
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  tables_[0] = Heap::undefined_value();
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Iterate(ObjectVisitor* v) {
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(&tables_[0], &tables_[generations_]);
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Clear() {
2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  MemsetPointer(tables_, Heap::undefined_value(), generations_);
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We only re-use a cached function for some script source code if the
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// script originates from the same place. This is to avoid issues
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// when reporting errors, etc.
2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool CompilationCacheScript::HasOrigin(
2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info,
2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Object> name,
2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int line_offset,
2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int column_offset) {
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script =
2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<Script>(Script::cast(function_info->script()));
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the script name isn't set, the boilerplate script should have
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an undefined name to have the same origin.
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (name.is_null()) {
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return script->name()->IsUndefined();
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do the fast bailout checks first.
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line_offset != script->line_offset()->value()) return false;
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (column_offset != script->column_offset()->value()) return false;
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check that both names are strings. If not, no match.
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!name->IsString() || !script->name()->IsString()) return false;
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare the two name strings for equality.
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return String::cast(*name)->Equals(String::cast(script->name()));
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(245): Need to allow identical code from different contexts to
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be cached in the same script generation. Currently the first use
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// will be cached, but subsequent code from different source / line
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// won't.
2576ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Probe the script generation tables. Make sure not to leak handles
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into the caller's handle scope.
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  { HandleScope scope;
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<Object> probe(table->Lookup(*source));
2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (probe->IsSharedFunctionInfo()) {
2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        Handle<SharedFunctionInfo> function_info =
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Handle<SharedFunctionInfo>::cast(probe);
2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        // Break when we've found a suitable shared function info that
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // matches the origin.
2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        if (HasOrigin(function_info, name, line_offset, column_offset)) {
2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          result = *function_info;
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void* script_histogram = StatsTable::CreateHistogram(
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      "V8.ScriptCache",
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      0,
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kScriptGenerations,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kScriptGenerations + 1);
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script_histogram != NULL) {
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    StatsTable::AddHistogramSample(script_histogram, generation);
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Once outside the manacles of the handle scope, we need to recheck
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to see if we actually found a cached script. If so, we return a
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handle created in the caller's handle scope.
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result != NULL) {
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(HasOrigin(shared, name, line_offset, column_offset));
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the script was found in a later generation, we promote it to
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the first generation to let it survive longer in the cache.
3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (generation != 0) Put(source, shared);
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_hits.Increment();
3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return shared;
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_misses.Increment();
3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3126ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheScript::TablePut(
3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
3146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CALL_HEAP_FUNCTION(GetFirstTable()->Put(*source, *function_info),
3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheScript::Put(Handle<String> source,
3216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, function_info));
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3276ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source, Handle<Context> context) {
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  { HandleScope scope;
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = table->LookupEval(*source, *context);
3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (result->IsSharedFunctionInfo()) {
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (result->IsSharedFunctionInfo()) {
3446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo>
3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        function_info(SharedFunctionInfo::cast(result));
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Put(source, context, function_info);
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_hits.Increment();
3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return function_info;
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_misses.Increment();
3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3586ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheEval::TablePut(
3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Context> context,
3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CALL_HEAP_FUNCTION(GetFirstTable()->PutEval(*source,
3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              *context,
3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              *function_info),
3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
3666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheEval::Put(Handle<String> source,
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               Handle<SharedFunctionInfo> function_info) {
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, context, function_info));
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  { HandleScope scope;
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = table->LookupRegExp(*source, flags);
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (result->IsFixedArray()) {
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFixedArray()) {
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> data(FixedArray::cast(result));
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Put(source, flags, data);
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_hits.Increment();
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return data;
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_misses.Increment();
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4076ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
4086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
4096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    JSRegExp::Flags flags,
4106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<FixedArray> data) {
4116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CALL_HEAP_FUNCTION(GetFirstTable()->PutRegExp(*source, flags, *data),
4126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
4136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheRegExp::Put(Handle<String> source,
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
4206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, flags, data));
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4246ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source,
4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
4276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
4296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return script.Lookup(source, name, line_offset, column_offset);
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4366ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupEval(Handle<String> source,
4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                        Handle<Context> context,
4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                        bool is_global) {
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = eval_global.Lookup(source, context);
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = eval_contextual.Lookup(source, context);
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reg_exp.Lookup(source, flags);
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutScript(Handle<String> source,
4646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  script.Put(source, function_info);
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutEval(Handle<String> source,
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               bool is_global,
4766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               Handle<SharedFunctionInfo> function_info) {
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    eval_global.Put(source, context, function_info);
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    eval_contextual.Put(source, context, function_info);
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutRegExp(Handle<String> source,
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  reg_exp.Put(source, flags, data);
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Clear() {
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    subcaches[i]->Clear();
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Iterate(ObjectVisitor* v) {
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    subcaches[i]->Iterate(v);
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::MarkCompactPrologue() {
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    subcaches[i]->Age();
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Enable() {
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enabled = true;
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Disable() {
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enabled = false;
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Clear();
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
535