説明を見る。00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "v8.h"
00029
00030 #include "compilation-cache.h"
00031
00032 namespace v8 { namespace internal {
00033
00034 enum {
00035 NUMBER_OF_ENTRY_KINDS = CompilationCache::LAST_ENTRY + 1
00036 };
00037
00038
00039
00040 static Object* tables[NUMBER_OF_ENTRY_KINDS] = { 0, };
00041
00042
00043 static Handle<CompilationCacheTable> AllocateTable(int size) {
00044 CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
00045 CompilationCacheTable);
00046 }
00047
00048
00049 static Handle<CompilationCacheTable> GetTable(CompilationCache::Entry entry) {
00050 Handle<CompilationCacheTable> result;
00051 if (tables[entry]->IsUndefined()) {
00052 static const int kInitialCacheSize = 64;
00053 result = AllocateTable(kInitialCacheSize);
00054 tables[entry] = *result;
00055 } else {
00056 CompilationCacheTable* table = CompilationCacheTable::cast(tables[entry]);
00057 result = Handle<CompilationCacheTable>(table);
00058 }
00059 return result;
00060 }
00061
00062
00063
00064
00065
00066 static bool HasOrigin(Handle<JSFunction> boilerplate,
00067 Handle<Object> name,
00068 int line_offset,
00069 int column_offset) {
00070 Handle<Script> script =
00071 Handle<Script>(Script::cast(boilerplate->shared()->script()));
00072
00073
00074 if (name.is_null()) {
00075 return script->name()->IsUndefined();
00076 }
00077
00078 if (line_offset != script->line_offset()->value()) return false;
00079 if (column_offset != script->column_offset()->value()) return false;
00080
00081 if (!name->IsString() || !script->name()->IsString()) return false;
00082
00083 return String::cast(*name)->Equals(String::cast(script->name()));
00084 }
00085
00086
00087 static Handle<JSFunction> Lookup(Handle<String> source,
00088 CompilationCache::Entry entry) {
00089
00090
00091
00092 Object* result;
00093 { HandleScope scope;
00094 Handle<CompilationCacheTable> table = GetTable(entry);
00095 result = table->Lookup(*source);
00096 }
00097 if (result->IsJSFunction()) {
00098 return Handle<JSFunction>(JSFunction::cast(result));
00099 } else {
00100 return Handle<JSFunction>::null();
00101 }
00102 }
00103
00104
00105 Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
00106 Handle<Object> name,
00107 int line_offset,
00108 int column_offset) {
00109 Handle<JSFunction> result = Lookup(source, SCRIPT);
00110 if (result.is_null()) {
00111 Counters::compilation_cache_misses.Increment();
00112 } else if (HasOrigin(result, name, line_offset, column_offset)) {
00113 Counters::compilation_cache_hits.Increment();
00114 } else {
00115 result = Handle<JSFunction>::null();
00116 Counters::compilation_cache_misses.Increment();
00117 }
00118 return result;
00119 }
00120
00121
00122 Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
00123 Entry entry) {
00124 ASSERT(entry == EVAL_GLOBAL || entry == EVAL_CONTEXTUAL);
00125 Handle<JSFunction> result = Lookup(source, entry);
00126 if (result.is_null()) {
00127 Counters::compilation_cache_misses.Increment();
00128 } else {
00129 Counters::compilation_cache_hits.Increment();
00130 }
00131 return result;
00132 }
00133
00134
00135 void CompilationCache::PutFunction(Handle<String> source,
00136 Entry entry,
00137 Handle<JSFunction> boilerplate) {
00138 HandleScope scope;
00139 ASSERT(boilerplate->IsBoilerplate());
00140 Handle<CompilationCacheTable> table = GetTable(entry);
00141 CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
00142 }
00143
00144
00145 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
00146 JSRegExp::Flags flags) {
00147 Handle<CompilationCacheTable> table = GetTable(REGEXP);
00148 Object* result = table->LookupRegExp(*source, flags);
00149 if (result->IsFixedArray()) {
00150 Counters::regexp_cache_hits.Increment();
00151 return Handle<FixedArray>(FixedArray::cast(result));
00152 } else {
00153 Counters::regexp_cache_misses.Increment();
00154 return Handle<FixedArray>();
00155 }
00156 }
00157
00158
00159 void CompilationCache::PutRegExp(Handle<String> source,
00160 JSRegExp::Flags flags,
00161 Handle<FixedArray> data) {
00162 HandleScope scope;
00163 Handle<CompilationCacheTable> table = GetTable(REGEXP);
00164 CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
00165 }
00166
00167
00168 void CompilationCache::Clear() {
00169 for (int i = 0; i < NUMBER_OF_ENTRY_KINDS; i++) {
00170 tables[i] = Heap::undefined_value();
00171 }
00172 }
00173
00174
00175 void CompilationCache::Iterate(ObjectVisitor* v) {
00176 v->VisitPointers(&tables[0], &tables[NUMBER_OF_ENTRY_KINDS]);
00177 }
00178
00179
00180 } }