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_, ®_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