13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 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
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "assembler.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h"
323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "serialize.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The number of generations for each sub cache.
393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The number of ScriptGenerations is carefully chosen based on histograms.
403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// See issue 458: http://code.google.com/p/v8/issues/detail?id=458
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kScriptGenerations = 5;
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalGlobalGenerations = 2;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalContextualGenerations = 2;
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kRegExpGenerations = 2;
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Initial size of each compilation cache table allocated.
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kInitialCacheSize = 64;
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockCompilationCache::CompilationCache(Isolate* isolate)
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : isolate_(isolate),
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      script_(isolate, kScriptGenerations),
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      eval_global_(isolate, kEvalGlobalGenerations),
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      eval_contextual_(isolate, kEvalContextualGenerations),
5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reg_exp_(isolate, kRegExpGenerations),
563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      enabled_(true) {
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
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochCompilationCache::~CompilationCache() {}
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic Handle<CompilationCacheTable> AllocateTable(Isolate* isolate, int size) {
6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate,
7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     CompilationCacheTable::Allocate(size),
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     CompilationCacheTable);
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(generation < generations_);
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<CompilationCacheTable> result;
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (tables_[generation]->IsUndefined()) {
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = AllocateTable(isolate(), kInitialCacheSize);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[generation] = *result;
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CompilationCacheTable* table =
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        CompilationCacheTable::cast(tables_[generation]);
8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = Handle<CompilationCacheTable>(table, isolate());
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Age() {
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Age the generations implicitly killing off the oldest.
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = generations_ - 1; i > 0; i--) {
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tables_[i] = tables_[i - 1];
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the first generation as unborn.
9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  tables_[0] = isolate()->heap()->undefined_value();
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
100756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationSubCache::IterateFunctions(ObjectVisitor* v) {
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* undefined = isolate()->heap()->raw_unchecked_undefined_value();
102756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  for (int i = 0; i < generations_; i++) {
103756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (tables_[i] != undefined) {
104756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v);
105756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    }
106756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
107756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
108756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
109756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Iterate(ObjectVisitor* v) {
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(&tables_[0], &tables_[generations_]);
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Clear() {
11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MemsetPointer(tables_, isolate()->heap()->undefined_value(), generations_);
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) {
121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Probe the script generation tables. Make sure not to leak handles
122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // into the caller's handle scope.
12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int generation = 0; generation < generations(); generation++) {
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Handle<CompilationCacheTable> table = GetTable(generation);
126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      table->Remove(*function_info);
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
13244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockCompilationCacheScript::CompilationCacheScript(Isolate* isolate,
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                               int generations)
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : CompilationSubCache(isolate, generations),
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      script_histogram_(NULL),
13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      script_histogram_initialized_(false) { }
13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We only re-use a cached function for some script source code if the
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// script originates from the same place. This is to avoid issues
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// when reporting errors, etc.
1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool CompilationCacheScript::HasOrigin(
1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info,
1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Object> name,
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int line_offset,
1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int column_offset) {
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script =
14844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Script>(Script::cast(function_info->script()), isolate());
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the script name isn't set, the boilerplate script should have
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an undefined name to have the same origin.
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (name.is_null()) {
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return script->name()->IsUndefined();
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do the fast bailout checks first.
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line_offset != script->line_offset()->value()) return false;
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (column_offset != script->column_offset()->value()) return false;
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check that both names are strings. If not, no match.
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!name->IsString() || !script->name()->IsString()) return false;
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare the two name strings for equality.
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return String::cast(*name)->Equals(String::cast(script->name()));
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(245): Need to allow identical code from different contexts to
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be cached in the same script generation. Currently the first use
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// will be cached, but subsequent code from different source / line
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// won't.
1686ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source,
1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Probe the script generation tables. Make sure not to leak handles
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into the caller's handle scope.
17744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object> probe(table->Lookup(*source), isolate());
1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (probe->IsSharedFunctionInfo()) {
1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        Handle<SharedFunctionInfo> function_info =
1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Handle<SharedFunctionInfo>::cast(probe);
1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        // Break when we've found a suitable shared function info that
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // matches the origin.
1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        if (HasOrigin(function_info, name, line_offset, column_offset)) {
1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          result = *function_info;
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!script_histogram_initialized_) {
19544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    script_histogram_ = isolate()->stats_table()->CreateHistogram(
19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        "V8.ScriptCache",
19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        0,
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        kScriptGenerations,
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        kScriptGenerations + 1);
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    script_histogram_initialized_ = true;
20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (script_histogram_ != NULL) {
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->stats_table()->AddHistogramSample(script_histogram_, generation);
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Once outside the manacles of the handle scope, we need to recheck
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to see if we actually found a cached script. If so, we return a
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handle created in the caller's handle scope.
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result != NULL) {
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result),
21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      isolate());
2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(HasOrigin(shared, name, line_offset, column_offset));
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the script was found in a later generation, we promote it to
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the first generation to let it survive longer in the cache.
2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (generation != 0) Put(source, shared);
21844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_hits()->Increment();
2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return shared;
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_misses()->Increment();
2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2275913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* CompilationCacheScript::TryTablePut(
2280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<String> source,
2290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<SharedFunctionInfo> function_info) {
2300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<CompilationCacheTable> table = GetFirstTable();
2310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return table->Put(*source, *function_info);
2320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
2330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2356ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheScript::TablePut(
2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo> function_info) {
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate(),
23944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     TryTablePut(source, function_info),
24044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     CompilationCacheTable);
2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheScript::Put(Handle<String> source,
2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, function_info));
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2516ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
2521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<String> source,
2531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<Context> context,
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LanguageMode language_mode,
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int scope_position) {
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
26144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      result = table->LookupEval(
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          *source, *context, language_mode, scope_position);
2666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (result->IsSharedFunctionInfo()) {
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (result->IsSharedFunctionInfo()) {
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<SharedFunctionInfo>
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        function_info(SharedFunctionInfo::cast(result), isolate());
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Put(source, context, function_info, scope_position);
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_hits()->Increment();
2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return function_info;
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_misses()->Increment();
2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2865913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* CompilationCacheEval::TryTablePut(
2870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<String> source,
2880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<Context> context,
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<SharedFunctionInfo> function_info,
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int scope_position) {
2910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<CompilationCacheTable> table = GetFirstTable();
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return table->PutEval(*source, *context, *function_info, scope_position);
2930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
2940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2966ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheEval::TablePut(
2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Context> context,
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<SharedFunctionInfo> function_info,
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int scope_position) {
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate(),
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     TryTablePut(
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         source, context, function_info, scope_position),
3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     CompilationCacheTable);
3056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheEval::Put(Handle<String> source,
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Handle<SharedFunctionInfo> function_info,
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               int scope_position) {
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SetFirstTable(TablePut(source, context, function_info, scope_position));
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure not to leak the table into the surrounding handle
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope. Otherwise, we risk keeping old tables around even after
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // having cleared the cache.
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result = NULL;
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int generation;
32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { HandleScope scope(isolate());
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (generation = 0; generation < generations(); generation++) {
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<CompilationCacheTable> table = GetTable(generation);
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = table->LookupRegExp(*source, flags);
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (result->IsFixedArray()) {
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsFixedArray()) {
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> data(FixedArray::cast(result), isolate());
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (generation != 0) {
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Put(source, flags, data);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_hits()->Increment();
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return data;
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate()->counters()->compilation_cache_misses()->Increment();
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3475913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* CompilationCacheRegExp::TryTablePut(
3480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<String> source,
3490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    JSRegExp::Flags flags,
3500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<FixedArray> data) {
3510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<CompilationCacheTable> table = GetFirstTable();
3520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return table->PutRegExp(*source, flags, *data);
3530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
3540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
3550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
3566ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<String> source,
3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    JSRegExp::Flags flags,
3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<FixedArray> data) {
36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate(),
36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     TryTablePut(source, flags, data),
36244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     CompilationCacheTable);
3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheRegExp::Put(Handle<String> source,
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFirstTable(TablePut(source, flags, data));
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (!IsEnabled()) return;
376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  eval_global_.Remove(function_info);
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  eval_contextual_.Remove(function_info);
37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  script_.Remove(function_info);
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3836ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source,
3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          Handle<Object> name,
3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int line_offset,
3866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                          int column_offset) {
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return script_.Lookup(source, name, line_offset, column_offset);
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3951e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupEval(
3961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<String> source,
3971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<Context> context,
3981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    bool is_global,
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LanguageMode language_mode,
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int scope_position) {
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    result = eval_global_.Lookup(
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        source, context, language_mode, scope_position);
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(scope_position != RelocInfo::kNoPosition);
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    result = eval_contextual_.Lookup(
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        source, context, language_mode, scope_position);
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  JSRegExp::Flags flags) {
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<FixedArray>::null();
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reg_exp_.Lookup(source, flags);
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutScript(Handle<String> source,
4296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 Handle<SharedFunctionInfo> function_info) {
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  script_.Put(source, function_info);
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutEval(Handle<String> source,
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Context> context,
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               bool is_global,
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Handle<SharedFunctionInfo> function_info,
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               int scope_position) {
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate());
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_global) {
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    eval_global_.Put(source, context, function_info, scope_position);
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(scope_position != RelocInfo::kNoPosition);
4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    eval_contextual_.Put(source, context, function_info, scope_position);
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutRegExp(Handle<String> source,
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSRegExp::Flags flags,
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Handle<FixedArray> data) {
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IsEnabled()) {
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  reg_exp_.Put(source, flags, data);
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Clear() {
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
47144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->Clear();
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
476756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::Iterate(ObjectVisitor* v) {
477756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  for (int i = 0; i < kSubCacheCount; i++) {
47844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->Iterate(v);
479756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
4807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
483756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::IterateFunctions(ObjectVisitor* v) {
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->IterateFunctions(v);
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::MarkCompactPrologue() {
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kSubCacheCount; i++) {
49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    subcaches_[i]->Age();
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Enable() {
49844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  enabled_ = true;
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Disable() {
50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  enabled_ = false;
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Clear();
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
509