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

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

Issue 411973002: Restructure the IC / Handler compilers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 int secondary_offset = SecondaryOffset(name, flags, primary_offset); 95 int secondary_offset = SecondaryOffset(name, flags, primary_offset);
96 Entry* secondary = entry(secondary_, secondary_offset); 96 Entry* secondary = entry(secondary_, secondary_offset);
97 if (secondary->key == name && secondary->map == map) { 97 if (secondary->key == name && secondary->map == map) {
98 return secondary->value; 98 return secondary->value;
99 } 99 }
100 return NULL; 100 return NULL;
101 } 101 }
102 102
103 103
104 Handle<Code> StubCache::FindIC(Handle<Name> name, Handle<Map> stub_holder, 104 Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
105 Code::Kind kind, ExtraICState extra_state, 105 Handle<Map> stub_holder, Code::Kind kind,
106 CacheHolderFlag cache_holder) { 106 ExtraICState extra_state,
107 CacheHolderFlag cache_holder) {
107 Code::Flags flags = Code::ComputeMonomorphicFlags( 108 Code::Flags flags = Code::ComputeMonomorphicFlags(
108 kind, extra_state, cache_holder); 109 kind, extra_state, cache_holder);
109 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); 110 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags),
111 name->GetIsolate());
110 if (probe->IsCode()) return Handle<Code>::cast(probe); 112 if (probe->IsCode()) return Handle<Code>::cast(probe);
111 return Handle<Code>::null(); 113 return Handle<Code>::null();
112 } 114 }
113 115
114 116
115 Handle<Code> StubCache::FindHandler(Handle<Name> name, Handle<Map> stub_holder, 117 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
116 Code::Kind kind, 118 Handle<Map> stub_holder,
117 CacheHolderFlag cache_holder, 119 Code::Kind kind,
118 Code::StubType type) { 120 CacheHolderFlag cache_holder,
121 Code::StubType type) {
119 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); 122 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
120 123
121 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); 124 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags),
125 name->GetIsolate());
122 if (probe->IsCode()) return Handle<Code>::cast(probe); 126 if (probe->IsCode()) return Handle<Code>::cast(probe);
123 return Handle<Code>::null(); 127 return Handle<Code>::null();
124 } 128 }
125 129
126 130
127 Handle<Code> StubCache::ComputeMonomorphicIC( 131 Handle<Code> StubCache::ComputeMonomorphicIC(
128 Code::Kind kind, 132 Code::Kind kind,
129 Handle<Name> name, 133 Handle<Name> name,
130 Handle<HeapType> type, 134 Handle<HeapType> type,
131 Handle<Code> handler, 135 Handle<Code> handler,
132 ExtraICState extra_ic_state) { 136 ExtraICState extra_ic_state) {
133 CacheHolderFlag flag; 137 CacheHolderFlag flag;
134 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate(), &flag); 138 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate(), &flag);
135 139
136 Handle<Code> ic; 140 Handle<Code> ic;
137 // There are multiple string maps that all use the same prototype. That 141 // There are multiple string maps that all use the same prototype. That
138 // prototype cannot hold multiple handlers, one for each of the string maps, 142 // prototype cannot hold multiple handlers, one for each of the string maps,
139 // for a single name. Hence, turn off caching of the IC. 143 // for a single name. Hence, turn off caching of the IC.
140 bool can_be_cached = !type->Is(HeapType::String()); 144 bool can_be_cached = !type->Is(HeapType::String());
141 if (can_be_cached) { 145 if (can_be_cached) {
142 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag); 146 ic =
147 PropertyICCompiler::Find(name, stub_holder, kind, extra_ic_state, flag);
143 if (!ic.is_null()) return ic; 148 if (!ic.is_null()) return ic;
144 } 149 }
145 150
146 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) { 151 #ifdef DEBUG
147 LoadStubCompiler ic_compiler(isolate(), kind, extra_ic_state, flag); 152 if (kind == Code::KEYED_STORE_IC) {
148 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
149 } else if (kind == Code::STORE_IC) {
150 StoreStubCompiler ic_compiler(isolate(), extra_ic_state);
151 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
152 } else {
153 ASSERT(kind == Code::KEYED_STORE_IC);
154 ASSERT(STANDARD_STORE == 153 ASSERT(STANDARD_STORE ==
155 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); 154 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
156 KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state);
157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
158 } 155 }
156 #endif
157
158 PropertyICCompiler ic_compiler(isolate(), kind, extra_ic_state, flag);
159 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
159 160
160 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); 161 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
161 return ic; 162 return ic;
162 } 163 }
163 164
164 165
165 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, 166 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
166 Handle<HeapType> type) { 167 Handle<HeapType> type) {
167 Handle<Map> receiver_map = IC::TypeToMap(*type, isolate()); 168 Handle<Map> receiver_map = IC::TypeToMap(*type, isolate());
168 if (receiver_map->prototype()->IsNull()) { 169 if (receiver_map->prototype()->IsNull()) {
(...skipping 19 matching lines...) Expand all
188 Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); 189 Handle<JSObject> last(JSObject::cast(receiver_map->prototype()));
189 while (true) { 190 while (true) {
190 if (current_map->is_dictionary_map()) cache_name = name; 191 if (current_map->is_dictionary_map()) cache_name = name;
191 if (current_map->prototype()->IsNull()) break; 192 if (current_map->prototype()->IsNull()) break;
192 last = handle(JSObject::cast(current_map->prototype())); 193 last = handle(JSObject::cast(current_map->prototype()));
193 current_map = handle(last->map()); 194 current_map = handle(last->map());
194 } 195 }
195 // Compile the stub that is either shared for all names or 196 // Compile the stub that is either shared for all names or
196 // name specific if there are global objects involved. 197 // name specific if there are global objects involved.
197 Code::Kind handler_kind = Code::LOAD_IC; 198 Code::Kind handler_kind = Code::LOAD_IC;
198 Handle<Code> handler = 199 Handle<Code> handler = PropertyHandlerCompiler::Find(
199 FindHandler(cache_name, stub_holder_map, handler_kind, flag, Code::FAST); 200 cache_name, stub_holder_map, handler_kind, flag, Code::FAST);
200 if (!handler.is_null()) { 201 if (!handler.is_null()) return handler;
201 return handler;
202 }
203 202
204 LoadStubCompiler compiler(isolate_, handler_kind, kNoExtraICState, flag); 203 NamedLoadHandlerCompiler compiler(isolate_, handler_kind, kNoExtraICState,
204 flag);
205 handler = compiler.CompileLoadNonexistent(type, last, cache_name); 205 handler = compiler.CompileLoadNonexistent(type, last, cache_name);
206 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); 206 Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
207 return handler; 207 return handler;
208 } 208 }
209 209
210 210
211 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 211 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
212 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 212 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
213 Handle<Name> name = 213 Handle<Name> name =
214 isolate()->factory()->KeyedLoadElementMonomorphic_string(); 214 isolate()->factory()->KeyedLoadElementMonomorphic_string();
215 215
216 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 216 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
217 if (probe->IsCode()) return Handle<Code>::cast(probe); 217 if (probe->IsCode()) return Handle<Code>::cast(probe);
218 218
219 KeyedLoadStubCompiler compiler(isolate()); 219 ElementsKind elements_kind = receiver_map->elements_kind();
220 Handle<Code> code = compiler.CompileLoadElement(receiver_map); 220 Handle<Code> stub;
221 if (receiver_map->has_fast_elements() ||
222 receiver_map->has_external_array_elements() ||
223 receiver_map->has_fixed_typed_array_elements()) {
224 stub = KeyedLoadFastElementStub(
225 isolate(), receiver_map->instance_type() == JS_ARRAY_TYPE,
226 elements_kind).GetCode();
227 } else {
228 stub = FLAG_compiled_keyed_dictionary_loads
229 ? KeyedLoadDictionaryElementStub(isolate()).GetCode()
230 : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode();
231 }
232 PropertyICCompiler compiler(isolate(), Code::KEYED_LOAD_IC);
233 Handle<Code> code =
234 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate()),
235 stub, factory()->empty_string(), ELEMENT);
221 236
222 Map::UpdateCodeCache(receiver_map, name, code); 237 Map::UpdateCodeCache(receiver_map, name, code);
223 return code; 238 return code;
224 } 239 }
225 240
226 241
227 Handle<Code> StubCache::ComputeKeyedStoreElement( 242 Handle<Code> StubCache::ComputeKeyedStoreElement(
228 Handle<Map> receiver_map, 243 Handle<Map> receiver_map,
229 StrictMode strict_mode, 244 StrictMode strict_mode,
230 KeyedAccessStoreMode store_mode) { 245 KeyedAccessStoreMode store_mode) {
231 ExtraICState extra_state = 246 ExtraICState extra_state =
232 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); 247 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
233 Code::Flags flags = 248 Code::Flags flags =
234 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state); 249 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state);
235 250
236 ASSERT(store_mode == STANDARD_STORE || 251 ASSERT(store_mode == STANDARD_STORE ||
237 store_mode == STORE_AND_GROW_NO_TRANSITION || 252 store_mode == STORE_AND_GROW_NO_TRANSITION ||
238 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 253 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
239 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 254 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
240 255
241 Handle<String> name = 256 Handle<String> name =
242 isolate()->factory()->KeyedStoreElementMonomorphic_string(); 257 isolate()->factory()->KeyedStoreElementMonomorphic_string();
243 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 258 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
244 if (probe->IsCode()) return Handle<Code>::cast(probe); 259 if (probe->IsCode()) return Handle<Code>::cast(probe);
245 260
246 KeyedStoreStubCompiler compiler(isolate(), extra_state); 261 PropertyICCompiler compiler(isolate(), Code::KEYED_STORE_IC, extra_state);
247 Handle<Code> code = compiler.CompileStoreElement(receiver_map); 262 Handle<Code> code =
263 compiler.CompileIndexedStoreMonomorphic(receiver_map, store_mode);
248 264
249 Map::UpdateCodeCache(receiver_map, name, code); 265 Map::UpdateCodeCache(receiver_map, name, code);
250 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) 266 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
251 == store_mode); 267 == store_mode);
252 return code; 268 return code;
253 } 269 }
254 270
255 271
256 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type) 272 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
257 273
(...skipping 20 matching lines...) Expand all
278 294
279 295
280 Handle<Code> StubCache::ComputeLoad(InlineCacheState ic_state, 296 Handle<Code> StubCache::ComputeLoad(InlineCacheState ic_state,
281 ExtraICState extra_state) { 297 ExtraICState extra_state) {
282 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state); 298 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
283 Handle<UnseededNumberDictionary> cache = 299 Handle<UnseededNumberDictionary> cache =
284 isolate_->factory()->non_monomorphic_cache(); 300 isolate_->factory()->non_monomorphic_cache();
285 int entry = cache->FindEntry(isolate_, flags); 301 int entry = cache->FindEntry(isolate_, flags);
286 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 302 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
287 303
288 StubCompiler compiler(isolate_); 304 PropertyICCompiler compiler(isolate_, Code::LOAD_IC);
289 Handle<Code> code; 305 Handle<Code> code;
290 if (ic_state == UNINITIALIZED) { 306 if (ic_state == UNINITIALIZED) {
291 code = compiler.CompileLoadInitialize(flags); 307 code = compiler.CompileLoadInitialize(flags);
292 } else if (ic_state == PREMONOMORPHIC) { 308 } else if (ic_state == PREMONOMORPHIC) {
293 code = compiler.CompileLoadPreMonomorphic(flags); 309 code = compiler.CompileLoadPreMonomorphic(flags);
294 } else if (ic_state == MEGAMORPHIC) { 310 } else if (ic_state == MEGAMORPHIC) {
295 code = compiler.CompileLoadMegamorphic(flags); 311 code = compiler.CompileLoadMegamorphic(flags);
296 } else { 312 } else {
297 UNREACHABLE(); 313 UNREACHABLE();
298 } 314 }
299 FillCache(isolate_, code); 315 FillCache(isolate_, code);
300 return code; 316 return code;
301 } 317 }
302 318
303 319
304 Handle<Code> StubCache::ComputeStore(InlineCacheState ic_state, 320 Handle<Code> StubCache::ComputeStore(InlineCacheState ic_state,
305 ExtraICState extra_state) { 321 ExtraICState extra_state) {
306 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state); 322 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state);
307 Handle<UnseededNumberDictionary> cache = 323 Handle<UnseededNumberDictionary> cache =
308 isolate_->factory()->non_monomorphic_cache(); 324 isolate_->factory()->non_monomorphic_cache();
309 int entry = cache->FindEntry(isolate_, flags); 325 int entry = cache->FindEntry(isolate_, flags);
310 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 326 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
311 327
312 StubCompiler compiler(isolate_); 328 PropertyICCompiler compiler(isolate_, Code::STORE_IC);
313 Handle<Code> code; 329 Handle<Code> code;
314 if (ic_state == UNINITIALIZED) { 330 if (ic_state == UNINITIALIZED) {
315 code = compiler.CompileStoreInitialize(flags); 331 code = compiler.CompileStoreInitialize(flags);
316 } else if (ic_state == PREMONOMORPHIC) { 332 } else if (ic_state == PREMONOMORPHIC) {
317 code = compiler.CompileStorePreMonomorphic(flags); 333 code = compiler.CompileStorePreMonomorphic(flags);
318 } else if (ic_state == GENERIC) { 334 } else if (ic_state == GENERIC) {
319 code = compiler.CompileStoreGeneric(flags); 335 code = compiler.CompileStoreGeneric(flags);
320 } else if (ic_state == MEGAMORPHIC) { 336 } else if (ic_state == MEGAMORPHIC) {
321 code = compiler.CompileStoreMegamorphic(flags); 337 code = compiler.CompileStoreMegamorphic(flags);
322 } else { 338 } else {
323 UNREACHABLE(); 339 UNREACHABLE();
324 } 340 }
325 341
326 FillCache(isolate_, code); 342 FillCache(isolate_, code);
327 return code; 343 return code;
328 } 344 }
329 345
330 346
331 Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map, 347 Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
332 CompareNilICStub* stub) { 348 CompareNilICStub* stub) {
333 Handle<String> name(isolate_->heap()->empty_string()); 349 Handle<String> name(isolate_->heap()->empty_string());
334 if (!receiver_map->is_shared()) { 350 if (!receiver_map->is_shared()) {
335 Handle<Code> cached_ic = FindIC(name, receiver_map, Code::COMPARE_NIL_IC, 351 Handle<Code> cached_ic = PropertyICCompiler::Find(
336 stub->GetExtraICState()); 352 name, receiver_map, Code::COMPARE_NIL_IC, stub->GetExtraICState());
337 if (!cached_ic.is_null()) return cached_ic; 353 if (!cached_ic.is_null()) return cached_ic;
338 } 354 }
339 355
340 Code::FindAndReplacePattern pattern; 356 Code::FindAndReplacePattern pattern;
341 pattern.Add(isolate_->factory()->meta_map(), receiver_map); 357 pattern.Add(isolate_->factory()->meta_map(), receiver_map);
342 Handle<Code> ic = stub->GetCodeCopy(pattern); 358 Handle<Code> ic = stub->GetCodeCopy(pattern);
343 359
344 if (!receiver_map->is_shared()) { 360 if (!receiver_map->is_shared()) {
345 Map::UpdateCodeCache(receiver_map, name, ic); 361 Map::UpdateCodeCache(receiver_map, name, ic);
346 } 362 }
347 363
348 return ic; 364 return ic;
349 } 365 }
350 366
351 367
352 // TODO(verwaest): Change this method so it takes in a TypeHandleList. 368 // TODO(verwaest): Change this method so it takes in a TypeHandleList.
353 Handle<Code> StubCache::ComputeLoadElementPolymorphic( 369 Handle<Code> StubCache::ComputeLoadElementPolymorphic(
354 MapHandleList* receiver_maps) { 370 MapHandleList* receiver_maps) {
355 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 371 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
356 Handle<PolymorphicCodeCache> cache = 372 Handle<PolymorphicCodeCache> cache =
357 isolate_->factory()->polymorphic_code_cache(); 373 isolate_->factory()->polymorphic_code_cache();
358 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 374 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
359 if (probe->IsCode()) return Handle<Code>::cast(probe); 375 if (probe->IsCode()) return Handle<Code>::cast(probe);
360 376
361 TypeHandleList types(receiver_maps->length()); 377 TypeHandleList types(receiver_maps->length());
362 for (int i = 0; i < receiver_maps->length(); i++) { 378 for (int i = 0; i < receiver_maps->length(); i++) {
363 types.Add(HeapType::Class(receiver_maps->at(i), isolate())); 379 types.Add(HeapType::Class(receiver_maps->at(i), isolate()));
364 } 380 }
365 CodeHandleList handlers(receiver_maps->length()); 381 CodeHandleList handlers(receiver_maps->length());
366 KeyedLoadStubCompiler compiler(isolate_); 382 IndexedHandlerCompiler compiler(isolate_);
367 compiler.CompileElementHandlers(receiver_maps, &handlers); 383 compiler.CompileElementHandlers(receiver_maps, &handlers);
368 LoadStubCompiler ic_compiler(isolate_, Code::KEYED_LOAD_IC); 384 PropertyICCompiler ic_compiler(isolate_, Code::KEYED_LOAD_IC);
369 Handle<Code> code = ic_compiler.CompilePolymorphicIC( 385 Handle<Code> code = ic_compiler.CompilePolymorphic(
370 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); 386 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT);
371 387
372 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); 388 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
373 389
374 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 390 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
375 return code; 391 return code;
376 } 392 }
377 393
378 394
379 Handle<Code> StubCache::ComputePolymorphicIC( 395 Handle<Code> StubCache::ComputePolymorphicIC(
380 Code::Kind kind, 396 Code::Kind kind,
381 TypeHandleList* types, 397 TypeHandleList* types,
382 CodeHandleList* handlers, 398 CodeHandleList* handlers,
383 int number_of_valid_types, 399 int number_of_valid_types,
384 Handle<Name> name, 400 Handle<Name> name,
385 ExtraICState extra_ic_state) { 401 ExtraICState extra_ic_state) {
386 Handle<Code> handler = handlers->at(0); 402 Handle<Code> handler = handlers->at(0);
387 Code::StubType type = number_of_valid_types == 1 ? handler->type() 403 Code::StubType type = number_of_valid_types == 1 ? handler->type()
388 : Code::NORMAL; 404 : Code::NORMAL;
389 if (kind == Code::LOAD_IC) { 405 ASSERT(kind == Code::LOAD_IC || kind == Code::STORE_IC);
390 LoadStubCompiler ic_compiler(isolate_, kind, extra_ic_state); 406 PropertyICCompiler ic_compiler(isolate_, kind, extra_ic_state);
391 return ic_compiler.CompilePolymorphicIC( 407 return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY);
392 types, handlers, name, type, PROPERTY);
393 } else {
394 ASSERT(kind == Code::STORE_IC);
395 StoreStubCompiler ic_compiler(isolate_, extra_ic_state);
396 return ic_compiler.CompilePolymorphicIC(
397 types, handlers, name, type, PROPERTY);
398 }
399 } 408 }
400 409
401 410
402 Handle<Code> StubCache::ComputeStoreElementPolymorphic( 411 Handle<Code> StubCache::ComputeStoreElementPolymorphic(
403 MapHandleList* receiver_maps, 412 MapHandleList* receiver_maps,
404 KeyedAccessStoreMode store_mode, 413 KeyedAccessStoreMode store_mode,
405 StrictMode strict_mode) { 414 StrictMode strict_mode) {
406 ASSERT(store_mode == STANDARD_STORE || 415 ASSERT(store_mode == STANDARD_STORE ||
407 store_mode == STORE_AND_GROW_NO_TRANSITION || 416 store_mode == STORE_AND_GROW_NO_TRANSITION ||
408 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 417 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
409 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 418 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
410 Handle<PolymorphicCodeCache> cache = 419 Handle<PolymorphicCodeCache> cache =
411 isolate_->factory()->polymorphic_code_cache(); 420 isolate_->factory()->polymorphic_code_cache();
412 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( 421 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(
413 strict_mode, store_mode); 422 strict_mode, store_mode);
414 Code::Flags flags = 423 Code::Flags flags =
415 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 424 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
416 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 425 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
417 if (probe->IsCode()) return Handle<Code>::cast(probe); 426 if (probe->IsCode()) return Handle<Code>::cast(probe);
418 427
419 KeyedStoreStubCompiler compiler(isolate_, extra_state); 428 PropertyICCompiler compiler(isolate_, Code::KEYED_STORE_IC, extra_state);
420 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps); 429 Handle<Code> code =
430 compiler.CompileIndexedStorePolymorphic(receiver_maps, store_mode);
421 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 431 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
422 return code; 432 return code;
423 } 433 }
424 434
425 435
426 void StubCache::Clear() { 436 void StubCache::Clear() {
427 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); 437 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
428 for (int i = 0; i < kPrimaryTableSize; i++) { 438 for (int i = 0; i < kPrimaryTableSize; i++) {
429 primary_[i].key = heap()->empty_string(); 439 primary_[i].key = heap()->empty_string();
430 primary_[i].map = NULL; 440 primary_[i].map = NULL;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 ASSERT(args.smi_at(1) >= 0); 631 ASSERT(args.smi_at(1) >= 0);
622 uint32_t index = args.smi_at(1); 632 uint32_t index = args.smi_at(1);
623 Handle<Object> result; 633 Handle<Object> result;
624 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 634 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
625 isolate, result, 635 isolate, result,
626 JSObject::GetElementWithInterceptor(receiver, receiver, index)); 636 JSObject::GetElementWithInterceptor(receiver, receiver, index));
627 return *result; 637 return *result;
628 } 638 }
629 639
630 640
631 Handle<Code> StubCompiler::CompileLoadInitialize(Code::Flags flags) { 641 Handle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) {
632 LoadIC::GenerateInitialize(masm()); 642 LoadIC::GenerateInitialize(masm());
633 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize"); 643 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize");
634 PROFILE(isolate(), 644 PROFILE(isolate(),
635 CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0)); 645 CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
636 return code; 646 return code;
637 } 647 }
638 648
639 649
640 Handle<Code> StubCompiler::CompileLoadPreMonomorphic(Code::Flags flags) { 650 Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
641 LoadIC::GeneratePreMonomorphic(masm()); 651 LoadIC::GeneratePreMonomorphic(masm());
642 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); 652 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic");
643 PROFILE(isolate(), 653 PROFILE(isolate(),
644 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); 654 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0));
645 return code; 655 return code;
646 } 656 }
647 657
648 658
649 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) { 659 Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
650 LoadIC::GenerateMegamorphic(masm()); 660 LoadIC::GenerateMegamorphic(masm());
651 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); 661 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic");
652 PROFILE(isolate(), 662 PROFILE(isolate(),
653 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0)); 663 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
654 return code; 664 return code;
655 } 665 }
656 666
657 667
658 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) { 668 Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
659 StoreIC::GenerateInitialize(masm()); 669 StoreIC::GenerateInitialize(masm());
660 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize"); 670 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");
661 PROFILE(isolate(), 671 PROFILE(isolate(),
662 CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0)); 672 CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
663 return code; 673 return code;
664 } 674 }
665 675
666 676
667 Handle<Code> StubCompiler::CompileStorePreMonomorphic(Code::Flags flags) { 677 Handle<Code> PropertyICCompiler::CompileStorePreMonomorphic(Code::Flags flags) {
668 StoreIC::GeneratePreMonomorphic(masm()); 678 StoreIC::GeneratePreMonomorphic(masm());
669 Handle<Code> code = GetCodeWithFlags(flags, "CompileStorePreMonomorphic"); 679 Handle<Code> code = GetCodeWithFlags(flags, "CompileStorePreMonomorphic");
670 PROFILE(isolate(), 680 PROFILE(isolate(),
671 CodeCreateEvent(Logger::STORE_PREMONOMORPHIC_TAG, *code, 0)); 681 CodeCreateEvent(Logger::STORE_PREMONOMORPHIC_TAG, *code, 0));
672 return code; 682 return code;
673 } 683 }
674 684
675 685
676 Handle<Code> StubCompiler::CompileStoreGeneric(Code::Flags flags) { 686 Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
677 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 687 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
678 StrictMode strict_mode = StoreIC::GetStrictMode(extra_state); 688 StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
679 StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode); 689 StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode);
680 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric"); 690 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
681 PROFILE(isolate(), 691 PROFILE(isolate(),
682 CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0)); 692 CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
683 return code; 693 return code;
684 } 694 }
685 695
686 696
687 Handle<Code> StubCompiler::CompileStoreMegamorphic(Code::Flags flags) { 697 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
688 StoreIC::GenerateMegamorphic(masm()); 698 StoreIC::GenerateMegamorphic(masm());
689 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); 699 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
690 PROFILE(isolate(), 700 PROFILE(isolate(),
691 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); 701 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
692 return code; 702 return code;
693 } 703 }
694 704
695 705
696 #undef CALL_LOGGER_TAG 706 #undef CALL_LOGGER_TAG
697 707
698 708
699 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 709 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
700 const char* name) { 710 const char* name) {
701 // Create code object in the heap. 711 // Create code object in the heap.
702 CodeDesc desc; 712 CodeDesc desc;
703 masm_.GetCode(&desc); 713 masm()->GetCode(&desc);
704 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); 714 Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject());
705 if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey()); 715 if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
706 #ifdef ENABLE_DISASSEMBLER 716 #ifdef ENABLE_DISASSEMBLER
707 if (FLAG_print_code_stubs) { 717 if (FLAG_print_code_stubs) {
708 OFStream os(stdout); 718 OFStream os(stdout);
709 code->Disassemble(name, os); 719 code->Disassemble(name, os);
710 } 720 }
711 #endif 721 #endif
712 return code; 722 return code;
713 } 723 }
714 724
715 725
716 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 726 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
717 Handle<Name> name) { 727 Handle<Name> name) {
718 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) 728 return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
719 ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get()) 729 ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get())
720 : GetCodeWithFlags(flags, NULL); 730 : GetCodeWithFlags(flags, NULL);
721 } 731 }
722 732
723 733
724 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
725 Handle<Name> name,
726 LookupResult* lookup) {
727 holder->LookupOwnRealNamedProperty(name, lookup);
728 if (lookup->IsFound()) return;
729 PrototypeIterator iter(holder->GetIsolate(), holder);
730 if (iter.IsAtEnd()) return;
731 PrototypeIterator::GetCurrent(iter)->Lookup(name, lookup);
732 }
733
734
735 #define __ ACCESS_MASM(masm()) 734 #define __ ACCESS_MASM(masm())
736 735
737 736
738 Register LoadStubCompiler::HandlerFrontendHeader( 737 Register NamedLoadHandlerCompiler::FrontendHeader(Handle<HeapType> type,
739 Handle<HeapType> type, 738 Register object_reg,
740 Register object_reg, 739 Handle<JSObject> holder,
741 Handle<JSObject> holder, 740 Handle<Name> name,
742 Handle<Name> name, 741 Label* miss) {
743 Label* miss) {
744 PrototypeCheckType check_type = CHECK_ALL_MAPS; 742 PrototypeCheckType check_type = CHECK_ALL_MAPS;
745 int function_index = -1; 743 int function_index = -1;
746 if (type->Is(HeapType::String())) { 744 if (type->Is(HeapType::String())) {
747 function_index = Context::STRING_FUNCTION_INDEX; 745 function_index = Context::STRING_FUNCTION_INDEX;
748 } else if (type->Is(HeapType::Symbol())) { 746 } else if (type->Is(HeapType::Symbol())) {
749 function_index = Context::SYMBOL_FUNCTION_INDEX; 747 function_index = Context::SYMBOL_FUNCTION_INDEX;
750 } else if (type->Is(HeapType::Number())) { 748 } else if (type->Is(HeapType::Number())) {
751 function_index = Context::NUMBER_FUNCTION_INDEX; 749 function_index = Context::NUMBER_FUNCTION_INDEX;
752 } else if (type->Is(HeapType::Boolean())) { 750 } else if (type->Is(HeapType::Boolean())) {
753 function_index = Context::BOOLEAN_FUNCTION_INDEX; 751 function_index = Context::BOOLEAN_FUNCTION_INDEX;
(...skipping 10 matching lines...) Expand all
764 object_reg = scratch1(); 762 object_reg = scratch1();
765 } 763 }
766 764
767 // Check that the maps starting from the prototype haven't changed. 765 // Check that the maps starting from the prototype haven't changed.
768 return CheckPrototypes( 766 return CheckPrototypes(
769 type, object_reg, holder, scratch1(), scratch2(), scratch3(), 767 type, object_reg, holder, scratch1(), scratch2(), scratch3(),
770 name, miss, check_type); 768 name, miss, check_type);
771 } 769 }
772 770
773 771
774 // HandlerFrontend for store uses the name register. It has to be restored 772 // Frontend for store uses the name register. It has to be restored before a
775 // before a miss. 773 // miss.
776 Register StoreStubCompiler::HandlerFrontendHeader( 774 Register NamedStoreHandlerCompiler::FrontendHeader(Handle<HeapType> type,
777 Handle<HeapType> type, 775 Register object_reg,
778 Register object_reg, 776 Handle<JSObject> holder,
779 Handle<JSObject> holder, 777 Handle<Name> name,
780 Handle<Name> name, 778 Label* miss) {
781 Label* miss) {
782 return CheckPrototypes(type, object_reg, holder, this->name(), 779 return CheckPrototypes(type, object_reg, holder, this->name(),
783 scratch1(), scratch2(), name, miss, SKIP_RECEIVER); 780 scratch1(), scratch2(), name, miss, SKIP_RECEIVER);
784 } 781 }
785 782
786 783
787 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { 784 bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
788 for (int i = 0; i < types->length(); ++i) { 785 for (int i = 0; i < types->length(); ++i) {
789 if (types->at(i)->Is(HeapType::Number())) return true; 786 if (types->at(i)->Is(HeapType::Number())) return true;
790 } 787 }
791 return false; 788 return false;
792 } 789 }
793 790
794 791
795 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<HeapType> type, 792 Register PropertyHandlerCompiler::Frontend(Handle<HeapType> type,
796 Register object_reg, 793 Register object_reg,
797 Handle<JSObject> holder, 794 Handle<JSObject> holder,
798 Handle<Name> name) { 795 Handle<Name> name) {
799 Label miss; 796 Label miss;
800 797 Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
801 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 798 FrontendFooter(name, &miss);
802
803 HandlerFrontendFooter(name, &miss);
804
805 return reg; 799 return reg;
806 } 800 }
807 801
808 802
809 void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type, 803 void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<HeapType> type,
810 Handle<JSObject> last, 804 Handle<JSObject> last,
811 Handle<Name> name) { 805 Handle<Name> name) {
812 Label miss; 806 Label miss;
813 807
814 Register holder; 808 Register holder;
815 Handle<Map> last_map; 809 Handle<Map> last_map;
816 if (last.is_null()) { 810 if (last.is_null()) {
817 holder = receiver(); 811 holder = receiver();
818 last_map = IC::TypeToMap(*type, isolate()); 812 last_map = IC::TypeToMap(*type, isolate());
819 // If |type| has null as its prototype, |last| is Handle<JSObject>::null(). 813 // If |type| has null as its prototype, |last| is Handle<JSObject>::null().
820 ASSERT(last_map->prototype() == isolate()->heap()->null_value()); 814 ASSERT(last_map->prototype() == isolate()->heap()->null_value());
821 } else { 815 } else {
822 holder = HandlerFrontendHeader(type, receiver(), last, name, &miss); 816 holder = FrontendHeader(type, receiver(), last, name, &miss);
823 last_map = handle(last->map()); 817 last_map = handle(last->map());
824 } 818 }
825 819
826 if (last_map->is_dictionary_map() && 820 if (last_map->is_dictionary_map() &&
827 !last_map->IsJSGlobalObjectMap() && 821 !last_map->IsJSGlobalObjectMap() &&
828 !last_map->IsJSGlobalProxyMap()) { 822 !last_map->IsJSGlobalProxyMap()) {
829 if (!name->IsUniqueName()) { 823 if (!name->IsUniqueName()) {
830 ASSERT(name->IsString()); 824 ASSERT(name->IsString());
831 name = factory()->InternalizeString(Handle<String>::cast(name)); 825 name = factory()->InternalizeString(Handle<String>::cast(name));
832 } 826 }
833 ASSERT(last.is_null() || 827 ASSERT(last.is_null() ||
834 last->property_dictionary()->FindEntry(name) == 828 last->property_dictionary()->FindEntry(name) ==
835 NameDictionary::kNotFound); 829 NameDictionary::kNotFound);
836 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, 830 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
837 scratch2(), scratch3()); 831 scratch2(), scratch3());
838 } 832 }
839 833
840 // If the last object in the prototype chain is a global object, 834 // If the last object in the prototype chain is a global object,
841 // check that the global property cell is empty. 835 // check that the global property cell is empty.
842 if (last_map->IsJSGlobalObjectMap()) { 836 if (last_map->IsJSGlobalObjectMap()) {
843 Handle<JSGlobalObject> global = last.is_null() 837 Handle<JSGlobalObject> global = last.is_null()
844 ? Handle<JSGlobalObject>::cast(type->AsConstant()->Value()) 838 ? Handle<JSGlobalObject>::cast(type->AsConstant()->Value())
845 : Handle<JSGlobalObject>::cast(last); 839 : Handle<JSGlobalObject>::cast(last);
846 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 840 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
847 } 841 }
848 842
849 HandlerFrontendFooter(name, &miss); 843 FrontendFooter(name, &miss);
850 } 844 }
851 845
852 846
853 Handle<Code> LoadStubCompiler::CompileLoadField( 847 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(
854 Handle<HeapType> type, 848 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
855 Handle<JSObject> holder, 849 FieldIndex field, Representation representation) {
856 Handle<Name> name, 850 Register reg = Frontend(type, receiver(), holder, name);
857 FieldIndex field,
858 Representation representation) {
859 Register reg = HandlerFrontend(type, receiver(), holder, name);
860 GenerateLoadField(reg, holder, field, representation); 851 GenerateLoadField(reg, holder, field, representation);
861
862 // Return the generated code.
863 return GetCode(kind(), Code::FAST, name); 852 return GetCode(kind(), Code::FAST, name);
864 } 853 }
865 854
866 855
867 Handle<Code> LoadStubCompiler::CompileLoadConstant( 856 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(
868 Handle<HeapType> type, 857 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
869 Handle<JSObject> holder,
870 Handle<Name> name,
871 Handle<Object> value) { 858 Handle<Object> value) {
872 HandlerFrontend(type, receiver(), holder, name); 859 Frontend(type, receiver(), holder, name);
873 GenerateLoadConstant(value); 860 GenerateLoadConstant(value);
874
875 // Return the generated code.
876 return GetCode(kind(), Code::FAST, name); 861 return GetCode(kind(), Code::FAST, name);
877 } 862 }
878 863
879 864
880 Handle<Code> LoadStubCompiler::CompileLoadCallback( 865 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
881 Handle<HeapType> type, 866 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
882 Handle<JSObject> holder,
883 Handle<Name> name,
884 Handle<ExecutableAccessorInfo> callback) { 867 Handle<ExecutableAccessorInfo> callback) {
885 Register reg = CallbackHandlerFrontend( 868 Register reg = CallbackFrontend(type, receiver(), holder, name, callback);
886 type, receiver(), holder, name, callback);
887 GenerateLoadCallback(reg, callback); 869 GenerateLoadCallback(reg, callback);
888
889 // Return the generated code.
890 return GetCode(kind(), Code::FAST, name); 870 return GetCode(kind(), Code::FAST, name);
891 } 871 }
892 872
893 873
894 Handle<Code> LoadStubCompiler::CompileLoadCallback( 874 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
895 Handle<HeapType> type, 875 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
896 Handle<JSObject> holder,
897 Handle<Name> name,
898 const CallOptimization& call_optimization) { 876 const CallOptimization& call_optimization) {
899 ASSERT(call_optimization.is_simple_api_call()); 877 ASSERT(call_optimization.is_simple_api_call());
900 Handle<JSFunction> callback = call_optimization.constant_function(); 878 Handle<JSFunction> callback = call_optimization.constant_function();
901 CallbackHandlerFrontend(type, receiver(), holder, name, callback); 879 CallbackFrontend(type, receiver(), holder, name, callback);
902 Handle<Map>receiver_map = IC::TypeToMap(*type, isolate()); 880 Handle<Map>receiver_map = IC::TypeToMap(*type, isolate());
903 GenerateFastApiCall( 881 GenerateFastApiCall(
904 masm(), call_optimization, receiver_map, 882 masm(), call_optimization, receiver_map,
905 receiver(), scratch1(), false, 0, NULL); 883 receiver(), scratch1(), false, 0, NULL);
906 // Return the generated code.
907 return GetCode(kind(), Code::FAST, name); 884 return GetCode(kind(), Code::FAST, name);
908 } 885 }
909 886
910 887
911 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( 888 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
912 Handle<HeapType> type, 889 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name) {
913 Handle<JSObject> holder, 890 // Perform a lookup after the interceptor.
914 Handle<Name> name) {
915 LookupResult lookup(isolate()); 891 LookupResult lookup(isolate());
916 LookupPostInterceptor(holder, name, &lookup); 892 holder->LookupOwnRealNamedProperty(name, &lookup);
893 if (!lookup.IsFound()) {
894 PrototypeIterator iter(holder->GetIsolate(), holder);
895 if (!iter.IsAtEnd()) {
896 PrototypeIterator::GetCurrent(iter)->Lookup(name, &lookup);
897 }
898 }
917 899
918 Register reg = HandlerFrontend(type, receiver(), holder, name); 900 Register reg = Frontend(type, receiver(), holder, name);
919 // TODO(368): Compile in the whole chain: all the interceptors in 901 // TODO(368): Compile in the whole chain: all the interceptors in
920 // prototypes and ultimate answer. 902 // prototypes and ultimate answer.
921 GenerateLoadInterceptor(reg, type, holder, &lookup, name); 903 GenerateLoadInterceptor(reg, type, holder, &lookup, name);
922
923 // Return the generated code.
924 return GetCode(kind(), Code::FAST, name); 904 return GetCode(kind(), Code::FAST, name);
925 } 905 }
926 906
927 907
928 void LoadStubCompiler::GenerateLoadPostInterceptor( 908 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
929 Register interceptor_reg, 909 Register interceptor_reg, Handle<JSObject> interceptor_holder,
930 Handle<JSObject> interceptor_holder, 910 Handle<Name> name, LookupResult* lookup) {
931 Handle<Name> name,
932 LookupResult* lookup) {
933 Handle<JSObject> holder(lookup->holder()); 911 Handle<JSObject> holder(lookup->holder());
934 if (lookup->IsField()) { 912 if (lookup->IsField()) {
935 FieldIndex field = lookup->GetFieldIndex(); 913 FieldIndex field = lookup->GetFieldIndex();
936 if (interceptor_holder.is_identical_to(holder)) { 914 if (interceptor_holder.is_identical_to(holder)) {
937 GenerateLoadField( 915 GenerateLoadField(
938 interceptor_reg, holder, field, lookup->representation()); 916 interceptor_reg, holder, field, lookup->representation());
939 } else { 917 } else {
940 // We found FIELD property in prototype chain of interceptor's holder. 918 // We found FIELD property in prototype chain of interceptor's holder.
941 // Retrieve a field from field's holder. 919 // Retrieve a field from field's holder.
942 Register reg = HandlerFrontend( 920 Register reg = Frontend(IC::CurrentTypeOf(interceptor_holder, isolate()),
943 IC::CurrentTypeOf(interceptor_holder, isolate()), 921 interceptor_reg, holder, name);
944 interceptor_reg, holder, name);
945 GenerateLoadField( 922 GenerateLoadField(
946 reg, holder, field, lookup->representation()); 923 reg, holder, field, lookup->representation());
947 } 924 }
948 } else { 925 } else {
949 // We found CALLBACKS property in prototype chain of interceptor's 926 // We found CALLBACKS property in prototype chain of interceptor's
950 // holder. 927 // holder.
951 ASSERT(lookup->type() == CALLBACKS); 928 ASSERT(lookup->type() == CALLBACKS);
952 Handle<ExecutableAccessorInfo> callback( 929 Handle<ExecutableAccessorInfo> callback(
953 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 930 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
954 ASSERT(callback->getter() != NULL); 931 ASSERT(callback->getter() != NULL);
955 932
956 Register reg = CallbackHandlerFrontend( 933 Register reg =
957 IC::CurrentTypeOf(interceptor_holder, isolate()), 934 CallbackFrontend(IC::CurrentTypeOf(interceptor_holder, isolate()),
958 interceptor_reg, holder, name, callback); 935 interceptor_reg, holder, name, callback);
959 GenerateLoadCallback(reg, callback); 936 GenerateLoadCallback(reg, callback);
960 } 937 }
961 } 938 }
962 939
963 940
964 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( 941 Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
965 Handle<HeapType> type, 942 Handle<Code> handler,
966 Handle<Code> handler, 943 Handle<Name> name,
967 Handle<Name> name) { 944 IcCheckType check) {
968 TypeHandleList types(1); 945 TypeHandleList types(1);
969 CodeHandleList handlers(1); 946 CodeHandleList handlers(1);
970 types.Add(type); 947 types.Add(type);
971 handlers.Add(handler); 948 handlers.Add(handler);
972 Code::StubType stub_type = handler->type(); 949 Code::StubType stub_type = handler->type();
973 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); 950 return CompilePolymorphic(&types, &handlers, name, stub_type, check);
974 } 951 }
975 952
976 953
977 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 954 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
978 Handle<HeapType> type, 955 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
979 Handle<JSObject> holder,
980 Handle<Name> name,
981 Handle<JSFunction> getter) { 956 Handle<JSFunction> getter) {
982 HandlerFrontend(type, receiver(), holder, name); 957 Frontend(type, receiver(), holder, name);
983 GenerateLoadViaGetter(masm(), type, receiver(), getter); 958 GenerateLoadViaGetter(masm(), type, receiver(), getter);
984
985 // Return the generated code.
986 return GetCode(kind(), Code::FAST, name); 959 return GetCode(kind(), Code::FAST, name);
987 } 960 }
988 961
989 962
990 Handle<Code> StoreStubCompiler::CompileStoreTransition( 963 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
991 Handle<JSObject> object, 964 Handle<JSObject> object, LookupResult* lookup, Handle<Map> transition,
992 LookupResult* lookup,
993 Handle<Map> transition,
994 Handle<Name> name) { 965 Handle<Name> name) {
995 Label miss, slow; 966 Label miss, slow;
996 967
997 // Ensure no transitions to deprecated maps are followed. 968 // Ensure no transitions to deprecated maps are followed.
998 __ CheckMapDeprecated(transition, scratch1(), &miss); 969 __ CheckMapDeprecated(transition, scratch1(), &miss);
999 970
1000 // Check that we are allowed to write this. 971 // Check that we are allowed to write this.
1001 PrototypeIterator iter(object->GetIsolate(), object); 972 PrototypeIterator iter(object->GetIsolate(), object);
1002 if (!iter.IsAtEnd()) { 973 if (!iter.IsAtEnd()) {
1003 Handle<JSObject> holder; 974 Handle<JSObject> holder;
1004 // holder == object indicates that no property was found. 975 // holder == object indicates that no property was found.
1005 if (lookup->holder() != *object) { 976 if (lookup->holder() != *object) {
1006 holder = Handle<JSObject>(lookup->holder()); 977 holder = Handle<JSObject>(lookup->holder());
1007 } else { 978 } else {
1008 // Find the top object. 979 // Find the top object.
1009 do { 980 do {
1010 holder = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 981 holder = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
1011 iter.Advance(); 982 iter.Advance();
1012 } while (!iter.IsAtEnd()); 983 } while (!iter.IsAtEnd());
1013 } 984 }
1014 985
1015 Register holder_reg = HandlerFrontendHeader( 986 Register holder_reg = FrontendHeader(IC::CurrentTypeOf(object, isolate()),
1016 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name, &miss); 987 receiver(), holder, name, &miss);
1017 988
1018 // If no property was found, and the holder (the last object in the 989 // If no property was found, and the holder (the last object in the
1019 // prototype chain) is in slow mode, we need to do a negative lookup on the 990 // prototype chain) is in slow mode, we need to do a negative lookup on the
1020 // holder. 991 // holder.
1021 if (lookup->holder() == *object) { 992 if (lookup->holder() == *object) {
1022 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); 993 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss);
1023 } 994 }
1024 } 995 }
1025 996
1026 GenerateStoreTransition(masm(), 997 GenerateStoreTransition(masm(),
1027 object, 998 object,
1028 lookup, 999 lookup,
1029 transition, 1000 transition,
1030 name, 1001 name,
1031 receiver(), this->name(), value(), 1002 receiver(), this->name(), value(),
1032 scratch1(), scratch2(), scratch3(), 1003 scratch1(), scratch2(), scratch3(),
1033 &miss, 1004 &miss,
1034 &slow); 1005 &slow);
1035 1006
1036 // Handle store cache miss. 1007 // Handle store cache miss.
1037 GenerateRestoreName(masm(), &miss, name); 1008 GenerateRestoreName(masm(), &miss, name);
1038 TailCallBuiltin(masm(), MissBuiltin(kind())); 1009 TailCallBuiltin(masm(), MissBuiltin(kind()));
1039 1010
1040 GenerateRestoreName(masm(), &slow, name); 1011 GenerateRestoreName(masm(), &slow, name);
1041 TailCallBuiltin(masm(), SlowBuiltin(kind())); 1012 TailCallBuiltin(masm(), SlowBuiltin(kind()));
1042
1043 // Return the generated code.
1044 return GetCode(kind(), Code::FAST, name); 1013 return GetCode(kind(), Code::FAST, name);
1045 } 1014 }
1046 1015
1047 1016
1048 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, 1017 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(
1049 LookupResult* lookup, 1018 Handle<JSObject> object, LookupResult* lookup, Handle<Name> name) {
1050 Handle<Name> name) {
1051 Label miss; 1019 Label miss;
1052 1020
1053 HandlerFrontendHeader(IC::CurrentTypeOf(object, isolate()), 1021 FrontendHeader(IC::CurrentTypeOf(object, isolate()), receiver(), object, name,
1054 receiver(), object, name, &miss); 1022 &miss);
1055 1023
1056 // Generate store field code. 1024 // Generate store field code.
1057 GenerateStoreField(masm(), 1025 GenerateStoreField(masm(),
1058 object, 1026 object,
1059 lookup, 1027 lookup,
1060 receiver(), this->name(), value(), scratch1(), scratch2(), 1028 receiver(), this->name(), value(), scratch1(), scratch2(),
1061 &miss); 1029 &miss);
1062 1030
1063 // Handle store cache miss. 1031 // Handle store cache miss.
1064 __ bind(&miss); 1032 __ bind(&miss);
1065 TailCallBuiltin(masm(), MissBuiltin(kind())); 1033 TailCallBuiltin(masm(), MissBuiltin(kind()));
1066
1067 // Return the generated code.
1068 return GetCode(kind(), Code::FAST, name); 1034 return GetCode(kind(), Code::FAST, name);
1069 } 1035 }
1070 1036
1071 1037
1072 Handle<Code> StoreStubCompiler::CompileStoreArrayLength(Handle<JSObject> object, 1038 Handle<Code> NamedStoreHandlerCompiler::CompileStoreArrayLength(
1073 LookupResult* lookup, 1039 Handle<JSObject> object, LookupResult* lookup, Handle<Name> name) {
1074 Handle<Name> name) {
1075 // This accepts as a receiver anything JSArray::SetElementsLength accepts 1040 // This accepts as a receiver anything JSArray::SetElementsLength accepts
1076 // (currently anything except for external arrays which means anything with 1041 // (currently anything except for external arrays which means anything with
1077 // elements of FixedArray type). Value must be a number, but only smis are 1042 // elements of FixedArray type). Value must be a number, but only smis are
1078 // accepted as the most common case. 1043 // accepted as the most common case.
1079 Label miss; 1044 Label miss;
1080 1045
1081 // Check that value is a smi. 1046 // Check that value is a smi.
1082 __ JumpIfNotSmi(value(), &miss); 1047 __ JumpIfNotSmi(value(), &miss);
1083 1048
1084 // Generate tail call to StoreIC_ArrayLength. 1049 // Generate tail call to StoreIC_ArrayLength.
1085 GenerateStoreArrayLength(); 1050 GenerateStoreArrayLength();
1086 1051
1087 // Handle miss case. 1052 // Handle miss case.
1088 __ bind(&miss); 1053 __ bind(&miss);
1089 TailCallBuiltin(masm(), MissBuiltin(kind())); 1054 TailCallBuiltin(masm(), MissBuiltin(kind()));
1090
1091 // Return the generated code.
1092 return GetCode(kind(), Code::FAST, name); 1055 return GetCode(kind(), Code::FAST, name);
1093 } 1056 }
1094 1057
1095 1058
1096 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( 1059 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
1097 Handle<JSObject> object, 1060 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
1098 Handle<JSObject> holder,
1099 Handle<Name> name,
1100 Handle<JSFunction> setter) { 1061 Handle<JSFunction> setter) {
1101 Handle<HeapType> type = IC::CurrentTypeOf(object, isolate()); 1062 Handle<HeapType> type = IC::CurrentTypeOf(object, isolate());
1102 HandlerFrontend(type, receiver(), holder, name); 1063 Frontend(type, receiver(), holder, name);
1103 GenerateStoreViaSetter(masm(), type, receiver(), setter); 1064 GenerateStoreViaSetter(masm(), type, receiver(), setter);
1104 1065
1105 return GetCode(kind(), Code::FAST, name); 1066 return GetCode(kind(), Code::FAST, name);
1106 } 1067 }
1107 1068
1108 1069
1109 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1070 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1110 Handle<JSObject> object, 1071 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
1111 Handle<JSObject> holder,
1112 Handle<Name> name,
1113 const CallOptimization& call_optimization) { 1072 const CallOptimization& call_optimization) {
1114 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 1073 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1115 receiver(), holder, name);
1116 Register values[] = { value() }; 1074 Register values[] = { value() };
1117 GenerateFastApiCall( 1075 GenerateFastApiCall(
1118 masm(), call_optimization, handle(object->map()), 1076 masm(), call_optimization, handle(object->map()),
1119 receiver(), scratch1(), true, 1, values); 1077 receiver(), scratch1(), true, 1, values);
1120 // Return the generated code.
1121 return GetCode(kind(), Code::FAST, name); 1078 return GetCode(kind(), Code::FAST, name);
1122 } 1079 }
1123 1080
1124 1081
1125 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 1082 Handle<Code> PropertyICCompiler::CompileIndexedStoreMonomorphic(
1126 Handle<Map> receiver_map) { 1083 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
1127 ElementsKind elements_kind = receiver_map->elements_kind();
1128 if (receiver_map->has_fast_elements() ||
1129 receiver_map->has_external_array_elements() ||
1130 receiver_map->has_fixed_typed_array_elements()) {
1131 Handle<Code> stub = KeyedLoadFastElementStub(
1132 isolate(),
1133 receiver_map->instance_type() == JS_ARRAY_TYPE,
1134 elements_kind).GetCode();
1135 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1136 } else {
1137 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads
1138 ? KeyedLoadDictionaryElementStub(isolate()).GetCode()
1139 : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode();
1140 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1141 }
1142
1143 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
1144
1145 // Return the generated code.
1146 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, MONOMORPHIC,
1147 extra_state(), Code::NORMAL);
1148 Handle<Code> code = GetCodeWithFlags(flags, factory()->empty_string());
1149 IC::RegisterWeakMapDependency(code);
1150 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
1151 heap()->empty_string()));
1152 return code;
1153 }
1154
1155
1156 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
1157 Handle<Map> receiver_map) {
1158 ElementsKind elements_kind = receiver_map->elements_kind(); 1084 ElementsKind elements_kind = receiver_map->elements_kind();
1159 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 1085 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
1160 Handle<Code> stub; 1086 Handle<Code> stub;
1161 if (receiver_map->has_fast_elements() || 1087 if (receiver_map->has_fast_elements() ||
1162 receiver_map->has_external_array_elements() || 1088 receiver_map->has_external_array_elements() ||
1163 receiver_map->has_fixed_typed_array_elements()) { 1089 receiver_map->has_fixed_typed_array_elements()) {
1164 stub = KeyedStoreFastElementStub( 1090 stub = KeyedStoreFastElementStub(isolate(), is_jsarray, elements_kind,
1165 isolate(), 1091 store_mode).GetCode();
1166 is_jsarray,
1167 elements_kind,
1168 store_mode()).GetCode();
1169 } else { 1092 } else {
1170 stub = KeyedStoreElementStub(isolate(), 1093 stub = KeyedStoreElementStub(isolate(), is_jsarray, elements_kind,
1171 is_jsarray, 1094 store_mode).GetCode();
1172 elements_kind,
1173 store_mode()).GetCode();
1174 } 1095 }
1175 1096
1176 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1097 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1177 1098
1178 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); 1099 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
1179 1100
1180 // Return the generated code. 1101 return GetCode(kind(), Code::NORMAL, factory()->empty_string());
1181 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
1182 } 1102 }
1183 1103
1184 1104
1185 #undef __ 1105 #undef __
1186 1106
1187 1107
1188 void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) { 1108 void PropertyAccessCompiler::TailCallBuiltin(MacroAssembler* masm,
1109 Builtins::Name name) {
1189 Handle<Code> code(masm->isolate()->builtins()->builtin(name)); 1110 Handle<Code> code(masm->isolate()->builtins()->builtin(name));
1190 GenerateTailCall(masm, code); 1111 GenerateTailCall(masm, code);
1191 } 1112 }
1192 1113
1193 1114
1194 void BaseLoadStoreStubCompiler::InitializeRegisters() { 1115 Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) {
1195 if (kind_ == Code::LOAD_IC) { 1116 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
1196 registers_ = LoadStubCompiler::registers(); 1117 return load_calling_convention();
1197 } else if (kind_ == Code::STORE_IC) { 1118 } else if (kind == Code::STORE_IC) {
1198 registers_ = StoreStubCompiler::registers(); 1119 return store_calling_convention();
1199 } else { 1120 } else {
1200 registers_ = KeyedStoreStubCompiler::registers(); 1121 ASSERT_EQ(Code::KEYED_STORE_IC, kind);
1122 return keyed_store_calling_convention();
1201 } 1123 }
1202 } 1124 }
1203 1125
1204 1126
1205 Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, 1127 Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type,
1206 Code::StubType type, 1128 Handle<Name> name,
1207 Handle<Name> name, 1129 InlineCacheState state) {
1208 InlineCacheState state) { 1130 Code::Flags flags =
1209 Code::Flags flags = Code::ComputeFlags(kind, state, extra_state(), type); 1131 Code::ComputeFlags(kind, state, extra_state(), type, cache_holder());
1210 Handle<Code> code = GetCodeWithFlags(flags, name); 1132 Handle<Code> code = GetCodeWithFlags(flags, name);
1211 IC::RegisterWeakMapDependency(code); 1133 IC::RegisterWeakMapDependency(code);
1212 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1134 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1213 return code; 1135 return code;
1214 } 1136 }
1215 1137
1216 1138
1217 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, 1139 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
1218 Code::StubType type, 1140 Code::StubType type,
1219 Handle<Name> name) { 1141 Handle<Name> name) {
1220 ASSERT_EQ(kNoExtraICState, extra_state()); 1142 ASSERT_EQ(kNoExtraICState, extra_state());
1221 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder_); 1143 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder());
1222 Handle<Code> code = GetCodeWithFlags(flags, name); 1144 Handle<Code> code = GetCodeWithFlags(flags, name);
1223 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1145 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name));
1224 return code; 1146 return code;
1225 } 1147 }
1226 1148
1227 1149
1228 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, 1150 void IndexedHandlerCompiler::CompileElementHandlers(
1229 CodeHandleList* handlers) { 1151 MapHandleList* receiver_maps, CodeHandleList* handlers) {
1230 for (int i = 0; i < receiver_maps->length(); ++i) { 1152 for (int i = 0; i < receiver_maps->length(); ++i) {
1231 Handle<Map> receiver_map = receiver_maps->at(i); 1153 Handle<Map> receiver_map = receiver_maps->at(i);
1232 Handle<Code> cached_stub; 1154 Handle<Code> cached_stub;
1233 1155
1234 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1156 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1235 cached_stub = isolate()->builtins()->KeyedLoadIC_String(); 1157 cached_stub = isolate()->builtins()->KeyedLoadIC_String();
1236 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 1158 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1237 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow(); 1159 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
1238 } else { 1160 } else {
1239 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1161 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
(...skipping 13 matching lines...) Expand all
1253 cached_stub = 1175 cached_stub =
1254 KeyedLoadDictionaryElementStub(isolate()).GetCode(); 1176 KeyedLoadDictionaryElementStub(isolate()).GetCode();
1255 } 1177 }
1256 } 1178 }
1257 1179
1258 handlers->Add(cached_stub); 1180 handlers->Add(cached_stub);
1259 } 1181 }
1260 } 1182 }
1261 1183
1262 1184
1263 Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic( 1185 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic(
1264 MapHandleList* receiver_maps) { 1186 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
1265 // Collect MONOMORPHIC stubs for all |receiver_maps|. 1187 // Collect MONOMORPHIC stubs for all |receiver_maps|.
1266 CodeHandleList handlers(receiver_maps->length()); 1188 CodeHandleList handlers(receiver_maps->length());
1267 MapHandleList transitioned_maps(receiver_maps->length()); 1189 MapHandleList transitioned_maps(receiver_maps->length());
1268 for (int i = 0; i < receiver_maps->length(); ++i) { 1190 for (int i = 0; i < receiver_maps->length(); ++i) {
1269 Handle<Map> receiver_map(receiver_maps->at(i)); 1191 Handle<Map> receiver_map(receiver_maps->at(i));
1270 Handle<Code> cached_stub; 1192 Handle<Code> cached_stub;
1271 Handle<Map> transitioned_map = 1193 Handle<Map> transitioned_map =
1272 receiver_map->FindTransitionedMap(receiver_maps); 1194 receiver_map->FindTransitionedMap(receiver_maps);
1273 1195
1274 // TODO(mvstanton): The code below is doing pessimistic elements 1196 // TODO(mvstanton): The code below is doing pessimistic elements
1275 // transitions. I would like to stop doing that and rely on Allocation Site 1197 // transitions. I would like to stop doing that and rely on Allocation Site
1276 // Tracking to do a better job of ensuring the data types are what they need 1198 // Tracking to do a better job of ensuring the data types are what they need
1277 // to be. Not all the elements are in place yet, pessimistic elements 1199 // to be. Not all the elements are in place yet, pessimistic elements
1278 // transitions are still important for performance. 1200 // transitions are still important for performance.
1279 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1201 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1280 ElementsKind elements_kind = receiver_map->elements_kind(); 1202 ElementsKind elements_kind = receiver_map->elements_kind();
1281 if (!transitioned_map.is_null()) { 1203 if (!transitioned_map.is_null()) {
1282 cached_stub = ElementsTransitionAndStoreStub( 1204 cached_stub =
1283 isolate(), 1205 ElementsTransitionAndStoreStub(isolate(), elements_kind,
1284 elements_kind, 1206 transitioned_map->elements_kind(),
1285 transitioned_map->elements_kind(), 1207 is_js_array, store_mode).GetCode();
1286 is_js_array,
1287 store_mode()).GetCode();
1288 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 1208 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1289 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow(); 1209 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
1290 } else { 1210 } else {
1291 if (receiver_map->has_fast_elements() || 1211 if (receiver_map->has_fast_elements() ||
1292 receiver_map->has_external_array_elements() || 1212 receiver_map->has_external_array_elements() ||
1293 receiver_map->has_fixed_typed_array_elements()) { 1213 receiver_map->has_fixed_typed_array_elements()) {
1294 cached_stub = KeyedStoreFastElementStub( 1214 cached_stub =
1295 isolate(), 1215 KeyedStoreFastElementStub(isolate(), is_js_array, elements_kind,
1296 is_js_array, 1216 store_mode).GetCode();
1297 elements_kind,
1298 store_mode()).GetCode();
1299 } else { 1217 } else {
1300 cached_stub = KeyedStoreElementStub( 1218 cached_stub =
1301 isolate(), 1219 KeyedStoreElementStub(isolate(), is_js_array, elements_kind,
1302 is_js_array, 1220 store_mode).GetCode();
1303 elements_kind,
1304 store_mode()).GetCode();
1305 } 1221 }
1306 } 1222 }
1307 ASSERT(!cached_stub.is_null()); 1223 ASSERT(!cached_stub.is_null());
1308 handlers.Add(cached_stub); 1224 handlers.Add(cached_stub);
1309 transitioned_maps.Add(transitioned_map); 1225 transitioned_maps.Add(transitioned_map);
1310 } 1226 }
1311 Handle<Code> code = 1227
1312 CompileStorePolymorphic(receiver_maps, &handlers, &transitioned_maps); 1228 Handle<Code> code = CompileIndexedStorePolymorphic(receiver_maps, &handlers,
1229 &transitioned_maps);
1313 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 1230 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1314 PROFILE(isolate(), 1231 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0));
1315 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0));
1316 return code; 1232 return code;
1317 } 1233 }
1318 1234
1319 1235
1320 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 1236 void IndexedHandlerCompiler::GenerateStoreDictionaryElement(
1321 MacroAssembler* masm) { 1237 MacroAssembler* masm) {
1322 KeyedStoreIC::GenerateSlow(masm); 1238 KeyedStoreIC::GenerateSlow(masm);
1323 } 1239 }
1324 1240
1325 1241
1326 CallOptimization::CallOptimization(LookupResult* lookup) { 1242 CallOptimization::CallOptimization(LookupResult* lookup) {
1327 if (lookup->IsFound() && 1243 if (lookup->IsFound() &&
1328 lookup->IsCacheable() && 1244 lookup->IsCacheable() &&
1329 lookup->IsConstantFunction()) { 1245 lookup->IsConstantFunction()) {
1330 // We only optimize constant function calls. 1246 // We only optimize constant function calls.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 Handle<FunctionTemplateInfo>( 1349 Handle<FunctionTemplateInfo>(
1434 FunctionTemplateInfo::cast(signature->receiver())); 1350 FunctionTemplateInfo::cast(signature->receiver()));
1435 } 1351 }
1436 } 1352 }
1437 1353
1438 is_simple_api_call_ = true; 1354 is_simple_api_call_ = true;
1439 } 1355 }
1440 1356
1441 1357
1442 } } // namespace v8::internal 1358 } } // namespace v8::internal
OLDNEW
« src/ia32/stub-cache-ia32.cc ('K') | « src/stub-cache.h ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698