Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/stub-cache.cc

Issue 422853003: Remove all compilation related interface from the StubCache (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Make the PropertyICCompiler constructor private Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/ast.h" 9 #include "src/ast.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 50
51 // Make sure that the code type and cache holder are not included in the hash. 51 // Make sure that the code type and cache holder are not included in the hash.
52 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 52 ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
53 ASSERT(Code::ExtractCacheHolderFromFlags(flags) == 0); 53 ASSERT(Code::ExtractCacheHolderFromFlags(flags) == 0);
54 54
55 return flags; 55 return flags;
56 } 56 }
57 57
58 58
59 Code* StubCache::Set(Name* name, Map* map, Code* code) { 59 Code* StubCache::Set(Name* name, Map* map, Code* code) {
60 Code::Flags flags = CommonStubCacheChecks(name, map, code->flags(), heap()); 60 Code::Flags flags =
61 CommonStubCacheChecks(name, map, code->flags(), isolate()->heap());
61 62
62 // Compute the primary entry. 63 // Compute the primary entry.
63 int primary_offset = PrimaryOffset(name, flags, map); 64 int primary_offset = PrimaryOffset(name, flags, map);
64 Entry* primary = entry(primary_, primary_offset); 65 Entry* primary = entry(primary_, primary_offset);
65 Code* old_code = primary->value; 66 Code* old_code = primary->value;
66 67
67 // If the primary entry has useful data in it, we retire it to the 68 // If the primary entry has useful data in it, we retire it to the
68 // secondary cache before overwriting it. 69 // secondary cache before overwriting it.
69 if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) { 70 if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
70 Map* old_map = primary->map; 71 Map* old_map = primary->map;
71 Code::Flags old_flags = 72 Code::Flags old_flags =
72 Code::RemoveTypeAndHolderFromFlags(old_code->flags()); 73 Code::RemoveTypeAndHolderFromFlags(old_code->flags());
73 int seed = PrimaryOffset(primary->key, old_flags, old_map); 74 int seed = PrimaryOffset(primary->key, old_flags, old_map);
74 int secondary_offset = SecondaryOffset(primary->key, old_flags, seed); 75 int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
75 Entry* secondary = entry(secondary_, secondary_offset); 76 Entry* secondary = entry(secondary_, secondary_offset);
76 *secondary = *primary; 77 *secondary = *primary;
77 } 78 }
78 79
79 // Update primary cache. 80 // Update primary cache.
80 primary->key = name; 81 primary->key = name;
81 primary->value = code; 82 primary->value = code;
82 primary->map = map; 83 primary->map = map;
83 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); 84 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
84 return code; 85 return code;
85 } 86 }
86 87
87 88
88 Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) { 89 Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) {
89 flags = CommonStubCacheChecks(name, map, flags, heap()); 90 flags = CommonStubCacheChecks(name, map, flags, isolate()->heap());
90 int primary_offset = PrimaryOffset(name, flags, map); 91 int primary_offset = PrimaryOffset(name, flags, map);
91 Entry* primary = entry(primary_, primary_offset); 92 Entry* primary = entry(primary_, primary_offset);
92 if (primary->key == name && primary->map == map) { 93 if (primary->key == name && primary->map == map) {
93 return primary->value; 94 return primary->value;
94 } 95 }
95 int secondary_offset = SecondaryOffset(name, flags, primary_offset); 96 int secondary_offset = SecondaryOffset(name, flags, primary_offset);
96 Entry* secondary = entry(secondary_, secondary_offset); 97 Entry* secondary = entry(secondary_, secondary_offset);
97 if (secondary->key == name && secondary->map == map) { 98 if (secondary->key == name && secondary->map == map) {
98 return secondary->value; 99 return secondary->value;
99 } 100 }
(...skipping 21 matching lines...) Expand all
121 Code::StubType type) { 122 Code::StubType type) {
122 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); 123 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
123 124
124 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), 125 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags),
125 name->GetIsolate()); 126 name->GetIsolate());
126 if (probe->IsCode()) return Handle<Code>::cast(probe); 127 if (probe->IsCode()) return Handle<Code>::cast(probe);
127 return Handle<Code>::null(); 128 return Handle<Code>::null();
128 } 129 }
129 130
130 131
131 Handle<Code> StubCache::ComputeMonomorphicIC( 132 Handle<Code> PropertyICCompiler::ComputeMonomorphicIC(
132 Code::Kind kind, 133 Code::Kind kind, Handle<Name> name, Handle<HeapType> type,
133 Handle<Name> name, 134 Handle<Code> handler, ExtraICState extra_ic_state) {
134 Handle<HeapType> type,
135 Handle<Code> handler,
136 ExtraICState extra_ic_state) {
137 CacheHolderFlag flag; 135 CacheHolderFlag flag;
138 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate(), &flag); 136 Isolate* isolate = name->GetIsolate();
137 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag);
139 138
140 Handle<Code> ic; 139 Handle<Code> ic;
141 // There are multiple string maps that all use the same prototype. That 140 // There are multiple string maps that all use the same prototype. That
142 // prototype cannot hold multiple handlers, one for each of the string maps, 141 // prototype cannot hold multiple handlers, one for each of the string maps,
143 // for a single name. Hence, turn off caching of the IC. 142 // for a single name. Hence, turn off caching of the IC.
144 bool can_be_cached = !type->Is(HeapType::String()); 143 bool can_be_cached = !type->Is(HeapType::String());
145 if (can_be_cached) { 144 if (can_be_cached) {
146 ic = 145 ic = Find(name, stub_holder, kind, extra_ic_state, flag);
147 PropertyICCompiler::Find(name, stub_holder, kind, extra_ic_state, flag);
148 if (!ic.is_null()) return ic; 146 if (!ic.is_null()) return ic;
149 } 147 }
150 148
151 #ifdef DEBUG 149 #ifdef DEBUG
152 if (kind == Code::KEYED_STORE_IC) { 150 if (kind == Code::KEYED_STORE_IC) {
153 ASSERT(STANDARD_STORE == 151 ASSERT(STANDARD_STORE ==
154 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); 152 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
155 } 153 }
156 #endif 154 #endif
157 155
158 PropertyICCompiler ic_compiler(isolate(), kind, extra_ic_state, flag); 156 PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
159 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); 157 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
160 158
161 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); 159 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
162 return ic; 160 return ic;
163 } 161 }
164 162
165 163
166 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, 164 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
167 Handle<HeapType> type) { 165 Handle<Name> name, Handle<HeapType> type) {
168 Handle<Map> receiver_map = IC::TypeToMap(*type, isolate()); 166 Isolate* isolate = name->GetIsolate();
167 Handle<Map> receiver_map = IC::TypeToMap(*type, isolate);
169 if (receiver_map->prototype()->IsNull()) { 168 if (receiver_map->prototype()->IsNull()) {
170 // TODO(jkummerow/verwaest): If there is no prototype and the property 169 // TODO(jkummerow/verwaest): If there is no prototype and the property
171 // is nonexistent, introduce a builtin to handle this (fast properties 170 // is nonexistent, introduce a builtin to handle this (fast properties
172 // -> return undefined, dictionary properties -> do negative lookup). 171 // -> return undefined, dictionary properties -> do negative lookup).
173 return Handle<Code>(); 172 return Handle<Code>();
174 } 173 }
175 CacheHolderFlag flag; 174 CacheHolderFlag flag;
176 Handle<Map> stub_holder_map = 175 Handle<Map> stub_holder_map =
177 IC::GetHandlerCacheHolder(*type, false, isolate(), &flag); 176 IC::GetHandlerCacheHolder(*type, false, isolate, &flag);
178 177
179 // If no dictionary mode objects are present in the prototype chain, the load 178 // If no dictionary mode objects are present in the prototype chain, the load
180 // nonexistent IC stub can be shared for all names for a given map and we use 179 // nonexistent IC stub can be shared for all names for a given map and we use
181 // the empty string for the map cache in that case. If there are dictionary 180 // the empty string for the map cache in that case. If there are dictionary
182 // mode objects involved, we need to do negative lookups in the stub and 181 // mode objects involved, we need to do negative lookups in the stub and
183 // therefore the stub will be specific to the name. 182 // therefore the stub will be specific to the name.
184 Handle<Name> cache_name = 183 Handle<Name> cache_name =
185 receiver_map->is_dictionary_map() 184 receiver_map->is_dictionary_map()
186 ? name 185 ? name
187 : Handle<Name>::cast(isolate()->factory()->nonexistent_symbol()); 186 : Handle<Name>::cast(isolate->factory()->nonexistent_symbol());
188 Handle<Map> current_map = stub_holder_map; 187 Handle<Map> current_map = stub_holder_map;
189 Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); 188 Handle<JSObject> last(JSObject::cast(receiver_map->prototype()));
190 while (true) { 189 while (true) {
191 if (current_map->is_dictionary_map()) cache_name = name; 190 if (current_map->is_dictionary_map()) cache_name = name;
192 if (current_map->prototype()->IsNull()) break; 191 if (current_map->prototype()->IsNull()) break;
193 last = handle(JSObject::cast(current_map->prototype())); 192 last = handle(JSObject::cast(current_map->prototype()));
194 current_map = handle(last->map()); 193 current_map = handle(last->map());
195 } 194 }
196 // Compile the stub that is either shared for all names or 195 // Compile the stub that is either shared for all names or
197 // name specific if there are global objects involved. 196 // name specific if there are global objects involved.
198 Handle<Code> handler = PropertyHandlerCompiler::Find( 197 Handle<Code> handler = PropertyHandlerCompiler::Find(
199 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); 198 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
200 if (!handler.is_null()) return handler; 199 if (!handler.is_null()) return handler;
201 200
202 NamedLoadHandlerCompiler compiler(isolate_, flag); 201 NamedLoadHandlerCompiler compiler(isolate, flag);
203 handler = compiler.CompileLoadNonexistent(type, last, cache_name); 202 handler = compiler.CompileLoadNonexistent(type, last, cache_name);
204 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); 203 Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
205 return handler; 204 return handler;
206 } 205 }
207 206
208 207
209 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 208 Handle<Code> PropertyICCompiler::ComputeKeyedLoadElement(
209 Handle<Map> receiver_map) {
210 Isolate* isolate = receiver_map->GetIsolate();
210 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 211 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
211 Handle<Name> name = 212 Handle<Name> name = isolate->factory()->KeyedLoadElementMonomorphic_string();
212 isolate()->factory()->KeyedLoadElementMonomorphic_string();
213 213
214 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 214 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
215 if (probe->IsCode()) return Handle<Code>::cast(probe); 215 if (probe->IsCode()) return Handle<Code>::cast(probe);
216 216
217 ElementsKind elements_kind = receiver_map->elements_kind(); 217 ElementsKind elements_kind = receiver_map->elements_kind();
218 Handle<Code> stub; 218 Handle<Code> stub;
219 if (receiver_map->has_fast_elements() || 219 if (receiver_map->has_fast_elements() ||
220 receiver_map->has_external_array_elements() || 220 receiver_map->has_external_array_elements() ||
221 receiver_map->has_fixed_typed_array_elements()) { 221 receiver_map->has_fixed_typed_array_elements()) {
222 stub = KeyedLoadFastElementStub( 222 stub = KeyedLoadFastElementStub(
223 isolate(), receiver_map->instance_type() == JS_ARRAY_TYPE, 223 isolate, receiver_map->instance_type() == JS_ARRAY_TYPE,
224 elements_kind).GetCode(); 224 elements_kind).GetCode();
225 } else { 225 } else {
226 stub = FLAG_compiled_keyed_dictionary_loads 226 stub = FLAG_compiled_keyed_dictionary_loads
227 ? KeyedLoadDictionaryElementStub(isolate()).GetCode() 227 ? KeyedLoadDictionaryElementStub(isolate).GetCode()
228 : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode(); 228 : KeyedLoadDictionaryElementPlatformStub(isolate).GetCode();
229 } 229 }
230 PropertyICCompiler compiler(isolate(), Code::KEYED_LOAD_IC); 230 PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
231 Handle<Code> code = 231 Handle<Code> code =
232 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate()), 232 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
233 stub, factory()->empty_string(), ELEMENT); 233 isolate->factory()->empty_string(), ELEMENT);
234 234
235 Map::UpdateCodeCache(receiver_map, name, code); 235 Map::UpdateCodeCache(receiver_map, name, code);
236 return code; 236 return code;
237 } 237 }
238 238
239 239
240 Handle<Code> StubCache::ComputeKeyedStoreElement( 240 Handle<Code> PropertyICCompiler::ComputeKeyedStoreElement(
241 Handle<Map> receiver_map, 241 Handle<Map> receiver_map, StrictMode strict_mode,
242 StrictMode strict_mode,
243 KeyedAccessStoreMode store_mode) { 242 KeyedAccessStoreMode store_mode) {
243 Isolate* isolate = receiver_map->GetIsolate();
244 ExtraICState extra_state = 244 ExtraICState extra_state =
245 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); 245 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
246 Code::Flags flags = 246 Code::Flags flags =
247 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state); 247 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state);
248 248
249 ASSERT(store_mode == STANDARD_STORE || 249 ASSERT(store_mode == STANDARD_STORE ||
250 store_mode == STORE_AND_GROW_NO_TRANSITION || 250 store_mode == STORE_AND_GROW_NO_TRANSITION ||
251 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 251 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
252 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 252 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
253 253
254 Handle<String> name = 254 Handle<String> name =
255 isolate()->factory()->KeyedStoreElementMonomorphic_string(); 255 isolate->factory()->KeyedStoreElementMonomorphic_string();
256 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 256 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
257 if (probe->IsCode()) return Handle<Code>::cast(probe); 257 if (probe->IsCode()) return Handle<Code>::cast(probe);
258 258
259 PropertyICCompiler compiler(isolate(), Code::KEYED_STORE_IC, extra_state); 259 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
260 Handle<Code> code = 260 Handle<Code> code =
261 compiler.CompileIndexedStoreMonomorphic(receiver_map, store_mode); 261 compiler.CompileIndexedStoreMonomorphic(receiver_map, store_mode);
262 262
263 Map::UpdateCodeCache(receiver_map, name, code); 263 Map::UpdateCodeCache(receiver_map, name, code);
264 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) 264 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
265 == store_mode); 265 == store_mode);
266 return code; 266 return code;
267 } 267 }
268 268
269 269
270 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type) 270 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
271 271
272 static void FillCache(Isolate* isolate, Handle<Code> code) { 272 static void FillCache(Isolate* isolate, Handle<Code> code) {
273 Handle<UnseededNumberDictionary> dictionary = 273 Handle<UnseededNumberDictionary> dictionary =
274 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 274 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
275 code->flags(), 275 code->flags(),
276 code); 276 code);
277 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 277 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
278 } 278 }
279 279
280 280
281 Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) { 281 Code* PropertyICCompiler::FindPreMonomorphicIC(Isolate* isolate,
282 Code::Kind kind,
283 ExtraICState state) {
282 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 284 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
283 UnseededNumberDictionary* dictionary = 285 UnseededNumberDictionary* dictionary =
284 isolate()->heap()->non_monomorphic_cache(); 286 isolate->heap()->non_monomorphic_cache();
285 int entry = dictionary->FindEntry(isolate(), flags); 287 int entry = dictionary->FindEntry(isolate, flags);
286 ASSERT(entry != -1); 288 ASSERT(entry != -1);
287 Object* code = dictionary->ValueAt(entry); 289 Object* code = dictionary->ValueAt(entry);
288 // This might be called during the marking phase of the collector 290 // This might be called during the marking phase of the collector
289 // hence the unchecked cast. 291 // hence the unchecked cast.
290 return reinterpret_cast<Code*>(code); 292 return reinterpret_cast<Code*>(code);
291 } 293 }
292 294
293 295
294 Handle<Code> StubCache::ComputeLoad(InlineCacheState ic_state, 296 Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate,
295 ExtraICState extra_state) { 297 InlineCacheState ic_state,
298 ExtraICState extra_state) {
296 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state); 299 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
297 Handle<UnseededNumberDictionary> cache = 300 Handle<UnseededNumberDictionary> cache =
298 isolate_->factory()->non_monomorphic_cache(); 301 isolate->factory()->non_monomorphic_cache();
299 int entry = cache->FindEntry(isolate_, flags); 302 int entry = cache->FindEntry(isolate, flags);
300 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 303 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
301 304
302 PropertyICCompiler compiler(isolate_, Code::LOAD_IC); 305 PropertyICCompiler compiler(isolate, Code::LOAD_IC);
303 Handle<Code> code; 306 Handle<Code> code;
304 if (ic_state == UNINITIALIZED) { 307 if (ic_state == UNINITIALIZED) {
305 code = compiler.CompileLoadInitialize(flags); 308 code = compiler.CompileLoadInitialize(flags);
306 } else if (ic_state == PREMONOMORPHIC) { 309 } else if (ic_state == PREMONOMORPHIC) {
307 code = compiler.CompileLoadPreMonomorphic(flags); 310 code = compiler.CompileLoadPreMonomorphic(flags);
308 } else if (ic_state == MEGAMORPHIC) { 311 } else if (ic_state == MEGAMORPHIC) {
309 code = compiler.CompileLoadMegamorphic(flags); 312 code = compiler.CompileLoadMegamorphic(flags);
310 } else { 313 } else {
311 UNREACHABLE(); 314 UNREACHABLE();
312 } 315 }
313 FillCache(isolate_, code); 316 FillCache(isolate, code);
314 return code; 317 return code;
315 } 318 }
316 319
317 320
318 Handle<Code> StubCache::ComputeStore(InlineCacheState ic_state, 321 Handle<Code> PropertyICCompiler::ComputeStore(Isolate* isolate,
319 ExtraICState extra_state) { 322 InlineCacheState ic_state,
323 ExtraICState extra_state) {
320 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state); 324 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state);
321 Handle<UnseededNumberDictionary> cache = 325 Handle<UnseededNumberDictionary> cache =
322 isolate_->factory()->non_monomorphic_cache(); 326 isolate->factory()->non_monomorphic_cache();
323 int entry = cache->FindEntry(isolate_, flags); 327 int entry = cache->FindEntry(isolate, flags);
324 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 328 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
325 329
326 PropertyICCompiler compiler(isolate_, Code::STORE_IC); 330 PropertyICCompiler compiler(isolate, Code::STORE_IC);
327 Handle<Code> code; 331 Handle<Code> code;
328 if (ic_state == UNINITIALIZED) { 332 if (ic_state == UNINITIALIZED) {
329 code = compiler.CompileStoreInitialize(flags); 333 code = compiler.CompileStoreInitialize(flags);
330 } else if (ic_state == PREMONOMORPHIC) { 334 } else if (ic_state == PREMONOMORPHIC) {
331 code = compiler.CompileStorePreMonomorphic(flags); 335 code = compiler.CompileStorePreMonomorphic(flags);
332 } else if (ic_state == GENERIC) { 336 } else if (ic_state == GENERIC) {
333 code = compiler.CompileStoreGeneric(flags); 337 code = compiler.CompileStoreGeneric(flags);
334 } else if (ic_state == MEGAMORPHIC) { 338 } else if (ic_state == MEGAMORPHIC) {
335 code = compiler.CompileStoreMegamorphic(flags); 339 code = compiler.CompileStoreMegamorphic(flags);
336 } else { 340 } else {
337 UNREACHABLE(); 341 UNREACHABLE();
338 } 342 }
339 343
340 FillCache(isolate_, code); 344 FillCache(isolate, code);
341 return code; 345 return code;
342 } 346 }
343 347
344 348
345 Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map, 349 Handle<Code> PropertyICCompiler::ComputeCompareNil(Handle<Map> receiver_map,
346 CompareNilICStub* stub) { 350 CompareNilICStub* stub) {
347 Handle<String> name(isolate_->heap()->empty_string()); 351 Isolate* isolate = receiver_map->GetIsolate();
352 Handle<String> name(isolate->heap()->empty_string());
348 if (!receiver_map->is_shared()) { 353 if (!receiver_map->is_shared()) {
349 Handle<Code> cached_ic = PropertyICCompiler::Find( 354 Handle<Code> cached_ic =
350 name, receiver_map, Code::COMPARE_NIL_IC, stub->GetExtraICState()); 355 Find(name, receiver_map, Code::COMPARE_NIL_IC, stub->GetExtraICState());
351 if (!cached_ic.is_null()) return cached_ic; 356 if (!cached_ic.is_null()) return cached_ic;
352 } 357 }
353 358
354 Code::FindAndReplacePattern pattern; 359 Code::FindAndReplacePattern pattern;
355 pattern.Add(isolate_->factory()->meta_map(), receiver_map); 360 pattern.Add(isolate->factory()->meta_map(), receiver_map);
356 Handle<Code> ic = stub->GetCodeCopy(pattern); 361 Handle<Code> ic = stub->GetCodeCopy(pattern);
357 362
358 if (!receiver_map->is_shared()) { 363 if (!receiver_map->is_shared()) {
359 Map::UpdateCodeCache(receiver_map, name, ic); 364 Map::UpdateCodeCache(receiver_map, name, ic);
360 } 365 }
361 366
362 return ic; 367 return ic;
363 } 368 }
364 369
365 370
366 // TODO(verwaest): Change this method so it takes in a TypeHandleList. 371 // TODO(verwaest): Change this method so it takes in a TypeHandleList.
367 Handle<Code> StubCache::ComputeLoadElementPolymorphic( 372 Handle<Code> PropertyICCompiler::ComputeLoadElementPolymorphic(
368 MapHandleList* receiver_maps) { 373 MapHandleList* receiver_maps) {
374 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
369 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 375 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
370 Handle<PolymorphicCodeCache> cache = 376 Handle<PolymorphicCodeCache> cache =
371 isolate_->factory()->polymorphic_code_cache(); 377 isolate->factory()->polymorphic_code_cache();
372 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 378 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
373 if (probe->IsCode()) return Handle<Code>::cast(probe); 379 if (probe->IsCode()) return Handle<Code>::cast(probe);
374 380
375 TypeHandleList types(receiver_maps->length()); 381 TypeHandleList types(receiver_maps->length());
376 for (int i = 0; i < receiver_maps->length(); i++) { 382 for (int i = 0; i < receiver_maps->length(); i++) {
377 types.Add(HeapType::Class(receiver_maps->at(i), isolate())); 383 types.Add(HeapType::Class(receiver_maps->at(i), isolate));
378 } 384 }
379 CodeHandleList handlers(receiver_maps->length()); 385 CodeHandleList handlers(receiver_maps->length());
380 IndexedHandlerCompiler compiler(isolate_); 386 IndexedHandlerCompiler compiler(isolate);
381 compiler.CompileElementHandlers(receiver_maps, &handlers); 387 compiler.CompileElementHandlers(receiver_maps, &handlers);
382 PropertyICCompiler ic_compiler(isolate_, Code::KEYED_LOAD_IC); 388 PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
383 Handle<Code> code = ic_compiler.CompilePolymorphic( 389 Handle<Code> code = ic_compiler.CompilePolymorphic(
384 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); 390 &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL,
391 ELEMENT);
385 392
386 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); 393 isolate->counters()->keyed_load_polymorphic_stubs()->Increment();
387 394
388 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 395 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
389 return code; 396 return code;
390 } 397 }
391 398
392 399
393 Handle<Code> StubCache::ComputePolymorphicIC( 400 Handle<Code> PropertyICCompiler::ComputePolymorphicIC(
394 Code::Kind kind, 401 Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers,
395 TypeHandleList* types, 402 int valid_types, Handle<Name> name, ExtraICState extra_ic_state) {
396 CodeHandleList* handlers,
397 int number_of_valid_types,
398 Handle<Name> name,
399 ExtraICState extra_ic_state) {
400 Handle<Code> handler = handlers->at(0); 403 Handle<Code> handler = handlers->at(0);
401 Code::StubType type = number_of_valid_types == 1 ? handler->type() 404 Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL;
402 : Code::NORMAL;
403 ASSERT(kind == Code::LOAD_IC || kind == Code::STORE_IC); 405 ASSERT(kind == Code::LOAD_IC || kind == Code::STORE_IC);
404 PropertyICCompiler ic_compiler(isolate_, kind, extra_ic_state); 406 PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state);
405 return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY); 407 return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY);
406 } 408 }
407 409
408 410
409 Handle<Code> StubCache::ComputeStoreElementPolymorphic( 411 Handle<Code> PropertyICCompiler::ComputeStoreElementPolymorphic(
410 MapHandleList* receiver_maps, 412 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
411 KeyedAccessStoreMode store_mode,
412 StrictMode strict_mode) { 413 StrictMode strict_mode) {
414 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
413 ASSERT(store_mode == STANDARD_STORE || 415 ASSERT(store_mode == STANDARD_STORE ||
414 store_mode == STORE_AND_GROW_NO_TRANSITION || 416 store_mode == STORE_AND_GROW_NO_TRANSITION ||
415 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 417 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
416 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 418 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
417 Handle<PolymorphicCodeCache> cache = 419 Handle<PolymorphicCodeCache> cache =
418 isolate_->factory()->polymorphic_code_cache(); 420 isolate->factory()->polymorphic_code_cache();
419 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( 421 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(
420 strict_mode, store_mode); 422 strict_mode, store_mode);
421 Code::Flags flags = 423 Code::Flags flags =
422 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 424 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
423 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 425 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
424 if (probe->IsCode()) return Handle<Code>::cast(probe); 426 if (probe->IsCode()) return Handle<Code>::cast(probe);
425 427
426 PropertyICCompiler compiler(isolate_, Code::KEYED_STORE_IC, extra_state); 428 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
427 Handle<Code> code = 429 Handle<Code> code =
428 compiler.CompileIndexedStorePolymorphic(receiver_maps, store_mode); 430 compiler.CompileIndexedStorePolymorphic(receiver_maps, store_mode);
429 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 431 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
430 return code; 432 return code;
431 } 433 }
432 434
433 435
434 void StubCache::Clear() { 436 void StubCache::Clear() {
435 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); 437 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
436 for (int i = 0; i < kPrimaryTableSize; i++) { 438 for (int i = 0; i < kPrimaryTableSize; i++) {
437 primary_[i].key = heap()->empty_string(); 439 primary_[i].key = isolate()->heap()->empty_string();
438 primary_[i].map = NULL; 440 primary_[i].map = NULL;
439 primary_[i].value = empty; 441 primary_[i].value = empty;
440 } 442 }
441 for (int j = 0; j < kSecondaryTableSize; j++) { 443 for (int j = 0; j < kSecondaryTableSize; j++) {
442 secondary_[j].key = heap()->empty_string(); 444 secondary_[j].key = isolate()->heap()->empty_string();
443 secondary_[j].map = NULL; 445 secondary_[j].map = NULL;
444 secondary_[j].value = empty; 446 secondary_[j].value = empty;
445 } 447 }
446 } 448 }
447 449
448 450
449 void StubCache::CollectMatchingMaps(SmallMapList* types, 451 void StubCache::CollectMatchingMaps(SmallMapList* types,
450 Handle<Name> name, 452 Handle<Name> name,
451 Code::Flags flags, 453 Code::Flags flags,
452 Handle<Context> native_context, 454 Handle<Context> native_context,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 520
519 521
520 /** 522 /**
521 * Attempts to load a property with an interceptor (which must be present), 523 * Attempts to load a property with an interceptor (which must be present),
522 * but doesn't search the prototype chain. 524 * but doesn't search the prototype chain.
523 * 525 *
524 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't 526 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
525 * provide any value for the given name. 527 * provide any value for the given name.
526 */ 528 */
527 RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) { 529 RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
528 ASSERT(args.length() == StubCache::kInterceptorArgsLength); 530 ASSERT(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
529 Handle<Name> name_handle = 531 Handle<Name> name_handle =
530 args.at<Name>(StubCache::kInterceptorArgsNameIndex); 532 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
531 Handle<InterceptorInfo> interceptor_info = 533 Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(
532 args.at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex); 534 NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex);
533 535
534 // TODO(rossberg): Support symbols in the API. 536 // TODO(rossberg): Support symbols in the API.
535 if (name_handle->IsSymbol()) 537 if (name_handle->IsSymbol())
536 return isolate->heap()->no_interceptor_result_sentinel(); 538 return isolate->heap()->no_interceptor_result_sentinel();
537 Handle<String> name = Handle<String>::cast(name_handle); 539 Handle<String> name = Handle<String>::cast(name_handle);
538 540
539 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); 541 Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
540 v8::NamedPropertyGetterCallback getter = 542 v8::NamedPropertyGetterCallback getter =
541 FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address); 543 FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
542 ASSERT(getter != NULL); 544 ASSERT(getter != NULL);
543 545
544 Handle<JSObject> receiver = 546 Handle<JSObject> receiver =
545 args.at<JSObject>(StubCache::kInterceptorArgsThisIndex); 547 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
546 Handle<JSObject> holder = 548 Handle<JSObject> holder =
547 args.at<JSObject>(StubCache::kInterceptorArgsHolderIndex); 549 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
548 PropertyCallbackArguments callback_args( 550 PropertyCallbackArguments callback_args(
549 isolate, interceptor_info->data(), *receiver, *holder); 551 isolate, interceptor_info->data(), *receiver, *holder);
550 { 552 {
551 // Use the interceptor getter. 553 // Use the interceptor getter.
552 HandleScope scope(isolate); 554 HandleScope scope(isolate);
553 v8::Handle<v8::Value> r = 555 v8::Handle<v8::Value> r =
554 callback_args.Call(getter, v8::Utils::ToLocal(name)); 556 callback_args.Call(getter, v8::Utils::ToLocal(name));
555 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 557 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
556 if (!r.IsEmpty()) { 558 if (!r.IsEmpty()) {
557 Handle<Object> result = v8::Utils::OpenHandle(*r); 559 Handle<Object> result = v8::Utils::OpenHandle(*r);
(...skipping 23 matching lines...) Expand all
581 return isolate->Throw(*error); 583 return isolate->Throw(*error);
582 } 584 }
583 585
584 586
585 /** 587 /**
586 * Loads a property with an interceptor performing post interceptor 588 * Loads a property with an interceptor performing post interceptor
587 * lookup if interceptor failed. 589 * lookup if interceptor failed.
588 */ 590 */
589 RUNTIME_FUNCTION(LoadPropertyWithInterceptor) { 591 RUNTIME_FUNCTION(LoadPropertyWithInterceptor) {
590 HandleScope scope(isolate); 592 HandleScope scope(isolate);
591 ASSERT(args.length() == StubCache::kInterceptorArgsLength); 593 ASSERT(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
592 Handle<Name> name = 594 Handle<Name> name =
593 args.at<Name>(StubCache::kInterceptorArgsNameIndex); 595 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
594 Handle<JSObject> receiver = 596 Handle<JSObject> receiver =
595 args.at<JSObject>(StubCache::kInterceptorArgsThisIndex); 597 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
596 Handle<JSObject> holder = 598 Handle<JSObject> holder =
597 args.at<JSObject>(StubCache::kInterceptorArgsHolderIndex); 599 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
598 600
599 Handle<Object> result; 601 Handle<Object> result;
600 LookupIterator it(receiver, name, holder); 602 LookupIterator it(receiver, name, holder);
601 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 603 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
602 isolate, result, JSObject::GetProperty(&it)); 604 isolate, result, JSObject::GetProperty(&it));
603 605
604 if (it.IsFound()) return *result; 606 if (it.IsFound()) return *result;
605 607
606 return ThrowReferenceError(isolate, Name::cast(args[0])); 608 return ThrowReferenceError(isolate, Name::cast(args[0]));
607 } 609 }
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 Handle<FunctionTemplateInfo>( 1357 Handle<FunctionTemplateInfo>(
1356 FunctionTemplateInfo::cast(signature->receiver())); 1358 FunctionTemplateInfo::cast(signature->receiver()));
1357 } 1359 }
1358 } 1360 }
1359 1361
1360 is_simple_api_call_ = true; 1362 is_simple_api_call_ = true;
1361 } 1363 }
1362 1364
1363 1365
1364 } } // namespace v8::internal 1366 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698