compilation-cache.cc revision 756813857a4c2a4d8ad2e805969d5768d3cf43a0
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);
84756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void IterateFunctions(ObjectVisitor* v);
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear this sub-cache evicting all its content.
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Clear();
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Number of generations in this sub-cache.
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int generations() { return generations_; }
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generations_;  // Number of generations.
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object** tables_;  // Compilation cache tables - one for each generation.
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for scripts.
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheScript : public CompilationSubCache {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationCacheScript(int generations)
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : CompilationSubCache(generations) { }
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> Lookup(Handle<String> source,
1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    Handle<Object> name,
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    int line_offset,
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    int column_offset);
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Note: Returns a new hash table if operation results in expansion.
1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> TablePut(
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<String> source, Handle<SharedFunctionInfo> function_info);
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool HasOrigin(Handle<SharedFunctionInfo> function_info,
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 Handle<Object> name,
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 int line_offset,
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                 int column_offset);
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for eval scripts.
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheEval: public CompilationSubCache {
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationCacheEval(int generations)
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : CompilationSubCache(generations) { }
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> Lookup(Handle<String> source,
1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    Handle<Context> context);
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Put(Handle<String> source,
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Handle<Context> context,
1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block           Handle<SharedFunctionInfo> function_info);
1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Note: Returns a new hash table if operation results in expansion.
1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> TablePut(
1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<String> source,
1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<Context> context,
1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<SharedFunctionInfo> function_info);
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for regular expressions.
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheRegExp: public CompilationSubCache {
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit CompilationCacheRegExp(int generations)
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : CompilationSubCache(generations) { }
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Put(Handle<String> source,
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           JSRegExp::Flags flags,
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Handle<FixedArray> data);
1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Note: Returns a new hash table if operation results in expansion.
1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<CompilationCacheTable> TablePut(Handle<String> source,
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         JSRegExp::Flags flags,
1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<FixedArray> data);
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Statically allocate all the sub-caches.
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheScript script(kScriptGenerations);
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_global(kEvalGlobalGenerations);
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_contextual(kEvalContextualGenerations);
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheRegExp reg_exp(kRegExpGenerations);
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationSubCache* subcaches[kSubCacheCount] =
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {&script, &eval_global, &eval_contextual, &reg_exp};
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Current enable state of the compilation cache.
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool enabled = true;
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool IsEnabled() {
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return FLAG_compilation_cache && enabled;
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<CompilationCacheTable> AllocateTable(int size) {
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     CompilationCacheTable);
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(generation < generations_);
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<CompilationCacheTable> result;
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (tables_[generation]->IsUndefined()) {
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = AllocateTable(kInitialCacheSize);
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[generation] = *result;
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CompilationCacheTable* table =
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        CompilationCacheTable::cast(tables_[generation]);
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = Handle<CompilationCacheTable>(table);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Age() {
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Age the generations implicitly killing off the oldest.
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = generations_ - 1; i > 0; i--) {
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[i] = tables_[i - 1];
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the first generation as unborn.
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  tables_[0] = Heap::undefined_value();
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
219756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationSubCache::IterateFunctions(ObjectVisitor* v) {
220756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  Object* undefined = Heap::raw_unchecked_undefined_value();
221756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  for (int i = 0; i < generations_; i++) {
222756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (tables_[i] != undefined) {
223756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v);
224756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    }
225756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
226756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
227756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
228756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Iterate(ObjectVisitor* v) {
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(&tables_[0], &tables_[generations_]);
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Clear() {
2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  MemsetPointer(tables_, Heap::undefined_value(), generations_);
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We only re-use a cached function for some script source code if the
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// script originates from the same place. This is to avoid issues
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// when reporting errors, etc.
2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool CompilationCacheScript::HasOrigin(
2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info,
2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Object> name,
2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int line_offset,
2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int column_offset) {
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script =
2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Handle<Script>(Script::cast(function_info->script()));
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the script name isn't set, the boilerplate script should have
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an undefined name to have the same origin.
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (name.is_null()) {
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return script->name()->IsUndefined();
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do the fast bailout checks first.
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line_offset != script->line_offset()->value()) return false;
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (column_offset != script->column_offset()->value()) return false;
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check that both names are strings. If not, no match.
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!name->IsString() || !script->name()->IsString()) return false;
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare the two name strings for equality.
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return String::cast(*name)->Equals(String::cast(script->name()));
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(245): Need to allow identical code from different contexts to
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be cached in the same script generation. Currently the first use
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// will be cached, but subsequent code from different source / line
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// won't.
2686ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Probe the script generation tables. Make sure not to leak handles
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into the caller's handle scope.
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  { HandleScope scope;
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<Object> probe(table->Lookup(*source));
2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (probe->IsSharedFunctionInfo()) {
2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        Handle<SharedFunctionInfo> function_info =
2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Handle<SharedFunctionInfo>::cast(probe);
2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        // Break when we've found a suitable shared function info that
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // matches the origin.
2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        if (HasOrigin(function_info, name, line_offset, column_offset)) {
2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          result = *function_info;
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void* script_histogram = StatsTable::CreateHistogram(
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      "V8.ScriptCache",
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      0,
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kScriptGenerations,
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kScriptGenerations + 1);
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script_histogram != NULL) {
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    StatsTable::AddHistogramSample(script_histogram, generation);
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Once outside the manacles of the handle scope, we need to recheck
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to see if we actually found a cached script. If so, we return a
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handle created in the caller's handle scope.
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result != NULL) {
3096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(HasOrigin(shared, name, line_offset, column_offset));
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the script was found in a later generation, we promote it to
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the first generation to let it survive longer in the cache.
3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (generation != 0) Put(source, shared);
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_hits.Increment();
3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return shared;
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_misses.Increment();
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3236ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheScript::TablePut(
3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CALL_HEAP_FUNCTION(GetFirstTable()->Put(*source, *function_info),
3276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheScript::Put(Handle<String> source,
3326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, function_info));
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3386ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source, Handle<Context> context) {
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  { HandleScope scope;
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = table->LookupEval(*source, *context);
3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (result->IsSharedFunctionInfo()) {
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (result->IsSharedFunctionInfo()) {
3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo>
3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        function_info(SharedFunctionInfo::cast(result));
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Put(source, context, function_info);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_hits.Increment();
3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return function_info;
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_misses.Increment();
3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3696ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheEval::TablePut(
3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Context> context,
3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CALL_HEAP_FUNCTION(GetFirstTable()->PutEval(*source,
3746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              *context,
3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              *function_info),
3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
3776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheEval::Put(Handle<String> source,
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               Handle<SharedFunctionInfo> function_info) {
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, context, function_info));
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  { HandleScope scope;
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = table->LookupRegExp(*source, flags);
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (result->IsFixedArray()) {
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFixedArray()) {
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> data(FixedArray::cast(result));
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Put(source, flags, data);
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_hits.Increment();
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return data;
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::compilation_cache_misses.Increment();
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4186ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
4196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
4206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    JSRegExp::Flags flags,
4216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<FixedArray> data) {
4226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CALL_HEAP_FUNCTION(GetFirstTable()->PutRegExp(*source, flags, *data),
4236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
4246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheRegExp::Put(Handle<String> source,
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, flags, data));
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4356ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source,
4366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return script.Lookup(source, name, line_offset, column_offset);
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4476ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupEval(Handle<String> source,
4486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                        Handle<Context> context,
4496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                        bool is_global) {
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
4516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = eval_global.Lookup(source, context);
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = eval_contextual.Lookup(source, context);
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reg_exp.Lookup(source, flags);
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutScript(Handle<String> source,
4756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  script.Put(source, function_info);
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutEval(Handle<String> source,
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               bool is_global,
4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               Handle<SharedFunctionInfo> function_info) {
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
4946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    eval_global.Put(source, context, function_info);
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    eval_contextual.Put(source, context, function_info);
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutRegExp(Handle<String> source,
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  reg_exp.Put(source, flags, data);
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Clear() {
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    subcaches[i]->Clear();
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
519756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::Iterate(ObjectVisitor* v) {
520756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  for (int i = 0; i < kSubCacheCount; i++) {
521756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    subcaches[i]->Iterate(v);
522756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
5237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
526756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::IterateFunctions(ObjectVisitor* v) {
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
528756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    subcaches[i]->IterateFunctions(v);
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::MarkCompactPrologue() {
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    subcaches[i]->Age();
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Enable() {
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enabled = true;
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Disable() {
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enabled = false;
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Clear();
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
552