compilation-cache.cc revision 6ded16be15dd865a9b21ea304d5273c8be299c87
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); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear this sub-cache evicting all its content. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Clear(); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Number of generations in this sub-cache. 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline int generations() { return generations_; } 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generations_; // Number of generations. 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** tables_; // Compilation cache tables - one for each generation. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache); 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for scripts. 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheScript : public CompilationSubCache { 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationCacheScript(int generations) 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : CompilationSubCache(generations) { } 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> Lookup(Handle<String> source, 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset); 1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Note: Returns a new hash table if operation results in expansion. 1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> TablePut( 1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, Handle<SharedFunctionInfo> function_info); 1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool HasOrigin(Handle<SharedFunctionInfo> function_info, 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> name, 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int line_offset, 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int column_offset); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for eval scripts. 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheEval: public CompilationSubCache { 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationCacheEval(int generations) 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : CompilationSubCache(generations) { } 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> Lookup(Handle<String> source, 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Put(Handle<String> source, 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context, 1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info); 1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Note: Returns a new hash table if operation results in expansion. 1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> TablePut( 1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info); 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sub-cache for regular expressions. 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheRegExp: public CompilationSubCache { 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompilationCacheRegExp(int generations) 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : CompilationSubCache(generations) { } 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Put(Handle<String> source, 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags, 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data); 1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Note: Returns a new hash table if operation results in expansion. 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<CompilationCacheTable> TablePut(Handle<String> source, 1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSRegExp::Flags flags, 1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<FixedArray> data); 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Statically allocate all the sub-caches. 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheScript script(kScriptGenerations); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_global(kEvalGlobalGenerations); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheEval eval_contextual(kEvalContextualGenerations); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationCacheRegExp reg_exp(kRegExpGenerations); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic CompilationSubCache* subcaches[kSubCacheCount] = 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {&script, &eval_global, &eval_contextual, ®_exp}; 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Current enable state of the compilation cache. 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool enabled = true; 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool IsEnabled() { 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return FLAG_compilation_cache && enabled; 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<CompilationCacheTable> AllocateTable(int size) { 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompilationCacheTable); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(generation < generations_); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> result; 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (tables_[generation]->IsUndefined()) { 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = AllocateTable(kInitialCacheSize); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_[generation] = *result; 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompilationCacheTable* table = 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompilationCacheTable::cast(tables_[generation]); 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Handle<CompilationCacheTable>(table); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Age() { 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Age the generations implicitly killing off the oldest. 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = generations_ - 1; i > 0; i--) { 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_[i] = tables_[i - 1]; 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the first generation as unborn. 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tables_[0] = Heap::undefined_value(); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Iterate(ObjectVisitor* v) { 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v->VisitPointers(&tables_[0], &tables_[generations_]); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationSubCache::Clear() { 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block MemsetPointer(tables_, Heap::undefined_value(), generations_); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We only re-use a cached function for some script source code if the 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// script originates from the same place. This is to avoid issues 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// when reporting errors, etc. 2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool CompilationCacheScript::HasOrigin( 2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info, 2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset) { 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script = 2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Script>(Script::cast(function_info->script())); 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script name isn't set, the boilerplate script should have 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an undefined name to have the same origin. 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (name.is_null()) { 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return script->name()->IsUndefined(); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do the fast bailout checks first. 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (line_offset != script->line_offset()->value()) return false; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (column_offset != script->column_offset()->value()) return false; 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that both names are strings. If not, no match. 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!name->IsString() || !script->name()->IsString()) return false; 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare the two name strings for equality. 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return String::cast(*name)->Equals(String::cast(script->name())); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(245): Need to allow identical code from different contexts to 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be cached in the same script generation. Currently the first use 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// will be cached, but subsequent code from different source / line 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// won't. 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(Handle<String> source, 2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset) { 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generation; 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Probe the script generation tables. Make sure not to leak handles 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // into the caller's handle scope. 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (generation = 0; generation < generations(); generation++) { 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> table = GetTable(generation); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> probe(table->Lookup(*source)); 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (probe->IsSharedFunctionInfo()) { 2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info = 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo>::cast(probe); 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Break when we've found a suitable shared function info that 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // matches the origin. 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (HasOrigin(function_info, name, line_offset, column_offset)) { 2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result = *function_info; 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void* script_histogram = StatsTable::CreateHistogram( 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "V8.ScriptCache", 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kScriptGenerations, 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kScriptGenerations + 1); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_histogram != NULL) { 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss. 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StatsTable::AddHistogramSample(script_histogram, generation); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Once outside the manacles of the handle scope, we need to recheck 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to see if we actually found a cached script. If so, we return a 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handle created in the caller's handle scope. 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result != NULL) { 2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); 2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(HasOrigin(shared, name, line_offset, column_offset)); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script was found in a later generation, we promote it to 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the first generation to let it survive longer in the cache. 3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (generation != 0) Put(source, shared); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_hits.Increment(); 3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return shared; 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_misses.Increment(); 3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3126ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheScript::TablePut( 3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 3146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CALL_HEAP_FUNCTION(GetFirstTable()->Put(*source, *function_info), 3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CompilationCacheTable); 3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheScript::Put(Handle<String> source, 3216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFirstTable(TablePut(source, function_info)); 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3276ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCacheEval::Lookup( 3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, Handle<Context> context) { 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure not to leak the table into the surrounding handle 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scope. Otherwise, we risk keeping old tables around even after 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // having cleared the cache. 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generation; 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (generation = 0; generation < generations(); generation++) { 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> table = GetTable(generation); 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = table->LookupEval(*source, *context); 3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (result->IsSharedFunctionInfo()) { 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (result->IsSharedFunctionInfo()) { 3446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> 3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info(SharedFunctionInfo::cast(result)); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (generation != 0) { 3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Put(source, context, function_info); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_hits.Increment(); 3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return function_info; 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_misses.Increment(); 3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheEval::TablePut( 3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CALL_HEAP_FUNCTION(GetFirstTable()->PutEval(*source, 3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block *context, 3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block *function_info), 3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CompilationCacheTable); 3666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheEval::Put(Handle<String> source, 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context, 3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFirstTable(TablePut(source, context, function_info)); 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source, 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags) { 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure not to leak the table into the surrounding handle 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scope. Otherwise, we risk keeping old tables around even after 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // having cleared the cache. 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int generation; 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (generation = 0; generation < generations(); generation++) { 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<CompilationCacheTable> table = GetTable(generation); 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = table->LookupRegExp(*source, flags); 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsFixedArray()) { 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsFixedArray()) { 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data(FixedArray::cast(result)); 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (generation != 0) { 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(source, flags, data); 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_hits.Increment(); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return data; 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::compilation_cache_misses.Increment(); 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<FixedArray>::null(); 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4076ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<CompilationCacheTable> CompilationCacheRegExp::TablePut( 4086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> source, 4096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSRegExp::Flags flags, 4106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<FixedArray> data) { 4116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CALL_HEAP_FUNCTION(GetFirstTable()->PutRegExp(*source, flags, *data), 4126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CompilationCacheTable); 4136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCacheRegExp::Put(Handle<String> source, 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags, 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data) { 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 4206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFirstTable(TablePut(source, flags, data)); 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4246ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source, 4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> name, 4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 4276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset) { 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 4296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return script.Lookup(source, name, line_offset, column_offset); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4366ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> CompilationCache::LookupEval(Handle<String> source, 4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool is_global) { 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result; 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_global) { 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = eval_global.Lookup(source, context); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = eval_contextual.Lookup(source, context); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags) { 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<FixedArray>::null(); 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reg_exp.Lookup(source, flags); 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutScript(Handle<String> source, 4646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block script.Put(source, function_info); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutEval(Handle<String> source, 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context, 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_global, 4766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_global) { 4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block eval_global.Put(source, context, function_info); 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block eval_contextual.Put(source, context, function_info); 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::PutRegExp(Handle<String> source, 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSRegExp::Flags flags, 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> data) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsEnabled()) { 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reg_exp.Put(source, flags, data); 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Clear() { 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kSubCacheCount; i++) { 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block subcaches[i]->Clear(); 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Iterate(ObjectVisitor* v) { 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kSubCacheCount; i++) { 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block subcaches[i]->Iterate(v); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::MarkCompactPrologue() { 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kSubCacheCount; i++) { 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block subcaches[i]->Age(); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Enable() { 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enabled = true; 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CompilationCache::Disable() { 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enabled = false; 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Clear(); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 535