compilation-cache.cc revision 44f0eee88ff00398ff7f715fab053374d808c90d
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
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The number of generations for each sub cache.
383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The number of ScriptGenerations is carefully chosen based on histograms.
393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// See issue 458: http://code.google.com/p/v8/issues/detail?id=458
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kScriptGenerations = 5;
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalGlobalGenerations = 2;
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalContextualGenerations = 2;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kRegExpGenerations = 2;
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Initial size of each compilation cache table allocated.
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kInitialCacheSize = 64;
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockCompilationCache::CompilationCache(Isolate* isolate)
5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : isolate_(isolate),
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      script_(isolate, kScriptGenerations),
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      eval_global_(isolate, kEvalGlobalGenerations),
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      eval_contextual_(isolate, kEvalContextualGenerations),
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reg_exp_(isolate, kRegExpGenerations),
5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      enabled_(true),
5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      eager_optimizing_set_(NULL) {
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CompilationSubCache* subcaches[kSubCacheCount] =
5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    {&script_, &eval_global_, &eval_contextual_, &reg_exp_};
5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  for (int i = 0; i < kSubCacheCount; ++i) {
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i] = subcaches[i];
616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockCompilationCache::~CompilationCache() {
6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete eager_optimizing_set_;
6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  eager_optimizing_set_ = NULL;
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic Handle<CompilationCacheTable> AllocateTable(Isolate* isolate, int size) {
7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate,
7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     CompilationCacheTable::Allocate(size),
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     CompilationCacheTable);
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(generation < generations_);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<CompilationCacheTable> result;
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (tables_[generation]->IsUndefined()) {
8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = AllocateTable(isolate(), kInitialCacheSize);
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[generation] = *result;
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CompilationCacheTable* table =
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        CompilationCacheTable::cast(tables_[generation]);
8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = Handle<CompilationCacheTable>(table, isolate());
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Age() {
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Age the generations implicitly killing off the oldest.
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = generations_ - 1; i > 0; i--) {
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[i] = tables_[i - 1];
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the first generation as unborn.
9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  tables_[0] = isolate()->heap()->undefined_value();
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
103756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationSubCache::IterateFunctions(ObjectVisitor* v) {
10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* undefined = isolate()->heap()->raw_unchecked_undefined_value();
105756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  for (int i = 0; i < generations_; i++) {
106756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (tables_[i] != undefined) {
107756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v);
108756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    }
109756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
110756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
111756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
112756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Iterate(ObjectVisitor* v) {
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(&tables_[0], &tables_[generations_]);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Clear() {
11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MemsetPointer(tables_, isolate()->heap()->undefined_value(), generations_);
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) {
124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Probe the script generation tables. Make sure not to leak handles
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // into the caller's handle scope.
12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int generation = 0; generation < generations(); generation++) {
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Handle<CompilationCacheTable> table = GetTable(generation);
129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      table->Remove(*function_info);
130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
13544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockCompilationCacheScript::CompilationCacheScript(Isolate* isolate,
13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                               int generations)
13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : CompilationSubCache(isolate, generations),
13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      script_histogram_(NULL),
13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      script_histogram_initialized_(false) { }
14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We only re-use a cached function for some script source code if the
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// script originates from the same place. This is to avoid issues
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// when reporting errors, etc.
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool CompilationCacheScript::HasOrigin(
1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info,
1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Object> name,
1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int line_offset,
1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int column_offset) {
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script =
15144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Script>(Script::cast(function_info->script()), isolate());
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the script name isn't set, the boilerplate script should have
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an undefined name to have the same origin.
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (name.is_null()) {
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return script->name()->IsUndefined();
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do the fast bailout checks first.
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line_offset != script->line_offset()->value()) return false;
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (column_offset != script->column_offset()->value()) return false;
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check that both names are strings. If not, no match.
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!name->IsString() || !script->name()->IsString()) return false;
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare the two name strings for equality.
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return String::cast(*name)->Equals(String::cast(script->name()));
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(245): Need to allow identical code from different contexts to
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be cached in the same script generation. Currently the first use
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// will be cached, but subsequent code from different source / line
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// won't.
1716ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Probe the script generation tables. Make sure not to leak handles
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into the caller's handle scope.
18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
18344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object> probe(table->Lookup(*source), isolate());
1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (probe->IsSharedFunctionInfo()) {
1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        Handle<SharedFunctionInfo> function_info =
1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Handle<SharedFunctionInfo>::cast(probe);
1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        // Break when we've found a suitable shared function info that
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // matches the origin.
1896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        if (HasOrigin(function_info, name, line_offset, column_offset)) {
1906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          result = *function_info;
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!script_histogram_initialized_) {
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    script_histogram_ = isolate()->stats_table()->CreateHistogram(
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        "V8.ScriptCache",
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block        0,
20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        kScriptGenerations,
20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        kScriptGenerations + 1);
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    script_histogram_initialized_ = true;
20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (script_histogram_ != NULL) {
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->stats_table()->AddHistogramSample(script_histogram_, generation);
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Once outside the manacles of the handle scope, we need to recheck
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to see if we actually found a cached script. If so, we return a
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handle created in the caller's handle scope.
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result != NULL) {
21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result),
21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      isolate());
2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(HasOrigin(shared, name, line_offset, column_offset));
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the script was found in a later generation, we promote it to
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the first generation to let it survive longer in the cache.
2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (generation != 0) Put(source, shared);
22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_hits()->Increment();
2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return shared;
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_misses()->Increment();
2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2305913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* CompilationCacheScript::TryTablePut(
2310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<String> source,
2320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<SharedFunctionInfo> function_info) {
2330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<CompilationCacheTable> table = GetFirstTable();
2340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return table->Put(*source, *function_info);
2350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
2360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2386ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheScript::TablePut(
2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
24144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate(),
24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     TryTablePut(source, function_info),
24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     CompilationCacheTable);
2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheScript::Put(Handle<String> source,
2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
2506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, function_info));
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2546ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
2551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<String> source,
2561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<Context> context,
2571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    StrictModeFlag strict_mode) {
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
2661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      result = table->LookupEval(*source, *context, strict_mode);
2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (result->IsSharedFunctionInfo()) {
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (result->IsSharedFunctionInfo()) {
2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo>
27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        function_info(SharedFunctionInfo::cast(result), isolate());
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Put(source, context, function_info);
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_hits()->Increment();
2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return function_info;
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_misses()->Increment();
2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2875913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* CompilationCacheEval::TryTablePut(
2880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<String> source,
2890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<Context> context,
2900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<SharedFunctionInfo> function_info) {
2910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<CompilationCacheTable> table = GetFirstTable();
2920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return table->PutEval(*source, *context, *function_info);
2930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
2940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2966ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheEval::TablePut(
2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Context> context,
2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate(),
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     TryTablePut(source, context, function_info),
3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheEval::Put(Handle<String> source,
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
3086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               Handle<SharedFunctionInfo> function_info) {
30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, context, function_info));
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = table->LookupRegExp(*source, flags);
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (result->IsFixedArray()) {
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFixedArray()) {
33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> data(FixedArray::cast(result), isolate());
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Put(source, flags, data);
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_hits()->Increment();
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return data;
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_misses()->Increment();
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3445913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* CompilationCacheRegExp::TryTablePut(
3450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<String> source,
3460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    JSRegExp::Flags flags,
3470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<FixedArray> data) {
3480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<CompilationCacheTable> table = GetFirstTable();
3490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return table->PutRegExp(*source, flags, *data);
3500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
3510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
3520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
3536ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    JSRegExp::Flags flags,
3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<FixedArray> data) {
35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate(),
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     TryTablePut(source, flags, data),
35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     CompilationCacheTable);
3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheRegExp::Put(Handle<String> source,
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, flags, data));
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (!IsEnabled()) return;
373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  eval_global_.Remove(function_info);
37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  eval_contextual_.Remove(function_info);
37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  script_.Remove(function_info);
377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3806ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source,
3816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return script_.Lookup(source, name, line_offset, column_offset);
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3921e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupEval(
3931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<String> source,
3941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<Context> context,
3951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    bool is_global,
3961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    StrictModeFlag strict_mode) {
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
3986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = eval_global_.Lookup(source, context, strict_mode);
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = eval_contextual_.Lookup(source, context, strict_mode);
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reg_exp_.Lookup(source, flags);
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutScript(Handle<String> source,
4226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  script_.Put(source, function_info);
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutEval(Handle<String> source,
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               bool is_global,
4346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               Handle<SharedFunctionInfo> function_info) {
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    eval_global_.Put(source, context, function_info);
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    eval_contextual_.Put(source, context, function_info);
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutRegExp(Handle<String> source,
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  reg_exp_.Put(source, flags, data);
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool SourceHashCompare(void* key1, void* key2) {
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return key1 == key2;
462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
46544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHashMap* CompilationCache::EagerOptimizingSet() {
46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (eager_optimizing_set_ == NULL) {
46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    eager_optimizing_set_ = new HashMap(&SourceHashCompare);
46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
46944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return eager_optimizing_set_;
470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool CompilationCache::ShouldOptimizeEagerly(Handle<JSFunction> function) {
474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_opt_eagerly) return true;
475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t hash = function->SourceHash();
476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void* key = reinterpret_cast<void*>(hash);
477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return EagerOptimizingSet()->Lookup(key, hash, false) != NULL;
478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationCache::MarkForEagerOptimizing(Handle<JSFunction> function) {
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t hash = function->SourceHash();
483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void* key = reinterpret_cast<void*>(hash);
484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  EagerOptimizingSet()->Lookup(key, hash, true);
485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationCache::MarkForLazyOptimizing(Handle<JSFunction> function) {
489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t hash = function->SourceHash();
490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void* key = reinterpret_cast<void*>(hash);
491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  EagerOptimizingSet()->Remove(key, hash);
492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationCache::ResetEagerOptimizingData() {
496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HashMap* set = EagerOptimizingSet();
497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (set->occupancy() > 0) set->Clear();
498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Clear() {
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->Clear();
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
508756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::Iterate(ObjectVisitor* v) {
509756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  for (int i = 0; i < kSubCacheCount; i++) {
51044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->Iterate(v);
511756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
5127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
515756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::IterateFunctions(ObjectVisitor* v) {
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->IterateFunctions(v);
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::MarkCompactPrologue() {
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->Age();
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Enable() {
53044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  enabled_ = true;
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Disable() {
53544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  enabled_ = false;
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Clear();
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
541