compilation-cache.cc revision 756813857a4c2a4d8ad2e805969d5768d3cf43a0
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h" 313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "serialize.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The number of sub caches covering the different types to cache. 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kSubCacheCount = 4; 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The number of generations for each sub cache. 403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The number of ScriptGenerations is carefully chosen based on histograms. 413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// See issue 458: http://code.google.com/p/v8/issues/detail?id=458 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kScriptGenerations = 5; 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalGlobalGenerations = 2; 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kEvalContextualGenerations = 2; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kRegExpGenerations = 2; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Initial size of each compilation cache table allocated. 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kInitialCacheSize = 64; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Index for the first generation in the cache. 516ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic const int kFirstGeneration = 0; 526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The compilation cache consists of several generational sub-caches which uses 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this class as a base class. A sub-cache contains a compilation cache tables 553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// for each generation of the sub-cache. Since the same source code string has 563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// different compiled code for scripts and evals, we use separate sub-caches 573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// for different compilation modes, to avoid retrieving the wrong result. 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationSubCache { 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationSubCache(int generations): generations_(generations) { 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_ = NewArray<Object*>(generations); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~CompilationSubCache() { DeleteArray(tables_); } 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the compilation cache tables for a specific generation. 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> GetTable(int generation); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Accessors for first generation. 706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> GetFirstTable() { 716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return GetTable(kFirstGeneration); 726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void SetFirstTable(Handle<CompilationCacheTable> value) { 746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(kFirstGeneration < generations_); 756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block tables_[kFirstGeneration] = *value; 766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Age the sub-cache by evicting the oldest generation and creating a new 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // young generation. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Age(); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GC support. 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Iterate(ObjectVisitor* v); 84756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void IterateFunctions(ObjectVisitor* v); 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear this sub-cache evicting all its content. 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Clear(); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Number of generations in this sub-cache. 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline int generations() { return generations_; } 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generations_; // Number of generations. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** tables_; // Compilation cache tables - one for each generation. 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for scripts. 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheScript : public CompilationSubCache { 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationCacheScript(int generations) 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : CompilationSubCache(generations) { } 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> Lookup(Handle<String> source, 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset); 1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Note: Returns a new hash table if operation results in expansion. 1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> TablePut( 1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, Handle<SharedFunctionInfo> function_info); 1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool HasOrigin(Handle<SharedFunctionInfo> function_info, 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> name, 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int line_offset, 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int column_offset); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for eval scripts. 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheEval: public CompilationSubCache { 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationCacheEval(int generations) 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : CompilationSubCache(generations) { } 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> Lookup(Handle<String> source, 1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Put(Handle<String> source, 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context, 1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info); 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Note: Returns a new hash table if operation results in expansion. 1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> TablePut( 1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for regular expressions. 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheRegExp: public CompilationSubCache { 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationCacheRegExp(int generations) 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : CompilationSubCache(generations) { } 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Put(Handle<String> source, 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags, 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data); 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Note: Returns a new hash table if operation results in expansion. 1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> TablePut(Handle<String> source, 1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSRegExp::Flags flags, 1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<FixedArray> data); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Statically allocate all the sub-caches. 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheScript script(kScriptGenerations); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_global(kEvalGlobalGenerations); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_contextual(kEvalContextualGenerations); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheRegExp reg_exp(kRegExpGenerations); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationSubCache* subcaches[kSubCacheCount] = 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {&script, &eval_global, &eval_contextual, ®_exp}; 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Current enable state of the compilation cache. 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool enabled = true; 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool IsEnabled() { 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return FLAG_compilation_cache && enabled; 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<CompilationCacheTable> AllocateTable(int size) { 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompilationCacheTable); 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(generation < generations_); 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> result; 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (tables_[generation]->IsUndefined()) { 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = AllocateTable(kInitialCacheSize); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_[generation] = *result; 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompilationCacheTable* table = 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompilationCacheTable::cast(tables_[generation]); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Handle<CompilationCacheTable>(table); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Age() { 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Age the generations implicitly killing off the oldest. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = generations_ - 1; i > 0; i--) { 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_[i] = tables_[i - 1]; 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the first generation as unborn. 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_[0] = Heap::undefined_value(); 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationSubCache::IterateFunctions(ObjectVisitor* v) { 220756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object* undefined = Heap::raw_unchecked_undefined_value(); 221756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (int i = 0; i < generations_; i++) { 222756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (tables_[i] != undefined) { 223756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick reinterpret_cast<CompilationCacheTable*>(tables_[i])->IterateElements(v); 224756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 225756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 226756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 227756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 228756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Iterate(ObjectVisitor* v) { 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v->VisitPointers(&tables_[0], &tables_[generations_]); 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Clear() { 2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block MemsetPointer(tables_, Heap::undefined_value(), generations_); 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We only re-use a cached function for some script source code if the 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// script originates from the same place. This is to avoid issues 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// when reporting errors, etc. 2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool CompilationCacheScript::HasOrigin( 2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info, 2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset) { 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script = 2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Script>(Script::cast(function_info->script())); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script name isn't set, the boilerplate script should have 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an undefined name to have the same origin. 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (name.is_null()) { 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return script->name()->IsUndefined(); 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do the fast bailout checks first. 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (line_offset != script->line_offset()->value()) return false; 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (column_offset != script->column_offset()->value()) return false; 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that both names are strings. If not, no match. 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!name->IsString() || !script->name()->IsString()) return false; 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare the two name strings for equality. 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return String::cast(*name)->Equals(String::cast(script->name())); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(245): Need to allow identical code from different contexts to 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be cached in the same script generation. Currently the first use 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// will be cached, but subsequent code from different source / line 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// won't. 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source, 2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset) { 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generation; 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Probe the script generation tables. Make sure not to leak handles 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // into the caller's handle scope. 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (generation = 0; generation < generations(); generation++) { 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> table = GetTable(generation); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> probe(table->Lookup(*source)); 2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (probe->IsSharedFunctionInfo()) { 2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info = 2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo>::cast(probe); 2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Break when we've found a suitable shared function info that 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // matches the origin. 2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (HasOrigin(function_info, name, line_offset, column_offset)) { 2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result = *function_info; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void* script_histogram = StatsTable::CreateHistogram( 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "V8.ScriptCache", 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kScriptGenerations, 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kScriptGenerations + 1); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_histogram != NULL) { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StatsTable::AddHistogramSample(script_histogram, generation); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Once outside the manacles of the handle scope, we need to recheck 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to see if we actually found a cached script. If so, we return a 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handle created in the caller's handle scope. 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result != NULL) { 3096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); 3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(HasOrigin(shared, name, line_offset, column_offset)); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script was found in a later generation, we promote it to 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the first generation to let it survive longer in the cache. 3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (generation != 0) Put(source, shared); 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_hits.Increment(); 3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return shared; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_misses.Increment(); 3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3236ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheScript::TablePut( 3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CALL_HEAP_FUNCTION(GetFirstTable()->Put(*source, *function_info), 3276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CompilationCacheTable); 3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheScript::Put(Handle<String> source, 3326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFirstTable(TablePut(source, function_info)); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3386ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheEval::Lookup( 3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, Handle<Context> context) { 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure not to leak the table into the surrounding handle 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scope. Otherwise, we risk keeping old tables around even after 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // having cleared the cache. 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generation; 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (generation = 0; generation < generations(); generation++) { 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> table = GetTable(generation); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = table->LookupEval(*source, *context); 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (result->IsSharedFunctionInfo()) { 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (result->IsSharedFunctionInfo()) { 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info(SharedFunctionInfo::cast(result)); 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (generation != 0) { 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Put(source, context, function_info); 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_hits.Increment(); 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return function_info; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_misses.Increment(); 3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3696ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheEval::TablePut( 3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CALL_HEAP_FUNCTION(GetFirstTable()->PutEval(*source, 3746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block *context, 3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block *function_info), 3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CompilationCacheTable); 3776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheEval::Put(Handle<String> source, 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context, 3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFirstTable(TablePut(source, context, function_info)); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source, 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags) { 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure not to leak the table into the surrounding handle 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scope. Otherwise, we risk keeping old tables around even after 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // having cleared the cache. 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generation; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (generation = 0; generation < generations(); generation++) { 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> table = GetTable(generation); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = table->LookupRegExp(*source, flags); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsFixedArray()) { 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsFixedArray()) { 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data(FixedArray::cast(result)); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (generation != 0) { 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(source, flags, data); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_hits.Increment(); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return data; 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_misses.Increment(); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<FixedArray>::null(); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4186ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheRegExp::TablePut( 4196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 4206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSRegExp::Flags flags, 4216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<FixedArray> data) { 4226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CALL_HEAP_FUNCTION(GetFirstTable()->PutRegExp(*source, flags, *data), 4236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CompilationCacheTable); 4246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheRegExp::Put(Handle<String> source, 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags, 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data) { 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFirstTable(TablePut(source, flags, data)); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4356ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source, 4366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset) { 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return script.Lookup(source, name, line_offset, column_offset); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4476ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupEval(Handle<String> source, 4486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 4496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool is_global) { 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 4516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result; 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_global) { 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = eval_global.Lookup(source, context); 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = eval_contextual.Lookup(source, context); 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags) { 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<FixedArray>::null(); 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reg_exp.Lookup(source, flags); 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutScript(Handle<String> source, 4756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block script.Put(source, function_info); 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutEval(Handle<String> source, 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context, 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_global, 4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_global) { 4946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block eval_global.Put(source, context, function_info); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block eval_contextual.Put(source, context, function_info); 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutRegExp(Handle<String> source, 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags, 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data) { 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reg_exp.Put(source, flags, data); 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Clear() { 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kSubCacheCount; i++) { 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block subcaches[i]->Clear(); 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 519756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::Iterate(ObjectVisitor* v) { 520756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (int i = 0; i < kSubCacheCount; i++) { 521756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick subcaches[i]->Iterate(v); 522756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 5237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 526756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid CompilationCache::IterateFunctions(ObjectVisitor* v) { 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kSubCacheCount; i++) { 528756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick subcaches[i]->IterateFunctions(v); 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::MarkCompactPrologue() { 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kSubCacheCount; i++) { 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block subcaches[i]->Age(); 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Enable() { 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enabled = true; 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Disable() { 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enabled = false; 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Clear(); 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 552