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

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

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 #ifndef V8_STUB_CACHE_H_ 5 #ifndef V8_STUB_CACHE_H_
6 #define V8_STUB_CACHE_H_ 6 #define V8_STUB_CACHE_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 class StubCache { 47 class StubCache {
48 public: 48 public:
49 struct Entry { 49 struct Entry {
50 Name* key; 50 Name* key;
51 Code* value; 51 Code* value;
52 Map* map; 52 Map* map;
53 }; 53 };
54 54
55 void Initialize(); 55 void Initialize();
56 56
57 Handle<JSObject> StubHolder(Handle<JSObject> receiver,
58 Handle<JSObject> holder);
59
60 Handle<Code> FindIC(Handle<Name> name, Handle<Map> stub_holder_map,
61 Code::Kind kind,
62 ExtraICState extra_state = kNoExtraICState,
63 CacheHolderFlag cache_holder = kCacheOnReceiver);
64
65 Handle<Code> FindHandler(Handle<Name> name, Handle<Map> map, Code::Kind kind,
66 CacheHolderFlag cache_holder, Code::StubType type);
67
68 Handle<Code> ComputeMonomorphicIC(Code::Kind kind, 57 Handle<Code> ComputeMonomorphicIC(Code::Kind kind,
69 Handle<Name> name, 58 Handle<Name> name,
70 Handle<HeapType> type, 59 Handle<HeapType> type,
71 Handle<Code> handler, 60 Handle<Code> handler,
72 ExtraICState extra_ic_state); 61 ExtraICState extra_ic_state);
73 62
74 Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<HeapType> type); 63 Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<HeapType> type);
75 64
76 Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map); 65 Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map);
77 66
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); 260 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly);
272 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); 261 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor);
273 DECLARE_RUNTIME_FUNCTION(StoreInterceptorProperty); 262 DECLARE_RUNTIME_FUNCTION(StoreInterceptorProperty);
274 DECLARE_RUNTIME_FUNCTION(KeyedLoadPropertyWithInterceptor); 263 DECLARE_RUNTIME_FUNCTION(KeyedLoadPropertyWithInterceptor);
275 264
276 265
277 enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER }; 266 enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
278 enum IcCheckType { ELEMENT, PROPERTY }; 267 enum IcCheckType { ELEMENT, PROPERTY };
279 268
280 269
281 // The stub compilers compile stubs for the stub cache. 270 class PropertyAccessCompiler BASE_EMBEDDED {
282 class StubCompiler BASE_EMBEDDED {
283 public: 271 public:
284 explicit StubCompiler(Isolate* isolate, 272 static Builtins::Name MissBuiltin(Code::Kind kind) {
285 ExtraICState extra_ic_state = kNoExtraICState) 273 switch (kind) {
286 : isolate_(isolate), extra_ic_state_(extra_ic_state), 274 case Code::LOAD_IC:
287 masm_(isolate, NULL, 256) { } 275 return Builtins::kLoadIC_Miss;
276 case Code::STORE_IC:
277 return Builtins::kStoreIC_Miss;
278 case Code::KEYED_LOAD_IC:
279 return Builtins::kKeyedLoadIC_Miss;
280 case Code::KEYED_STORE_IC:
281 return Builtins::kKeyedStoreIC_Miss;
282 default:
283 UNREACHABLE();
284 }
285 return Builtins::kLoadIC_Miss;
286 }
287
288 static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
289
290 protected:
291 PropertyAccessCompiler(Isolate* isolate, Code::Kind kind,
292 ExtraICState extra_ic_state,
293 CacheHolderFlag cache_holder)
294 : registers_(GetCallingConvention(kind)),
295 kind_(kind),
296 cache_holder_(cache_holder),
297 isolate_(isolate),
298 extra_ic_state_(extra_ic_state),
299 masm_(isolate, NULL, 256) {}
300
301 Code::Kind kind() const { return kind_; }
302 CacheHolderFlag cache_holder() const { return cache_holder_; }
303 ExtraICState extra_state() const { return extra_ic_state_; }
304 MacroAssembler* masm() { return &masm_; }
305 Isolate* isolate() const { return isolate_; }
306 Heap* heap() const { return isolate()->heap(); }
307 Factory* factory() const { return isolate()->factory(); }
308
309 Register receiver() const { return registers_[0]; }
310 Register name() const { return registers_[1]; }
311 Register scratch1() const { return registers_[2]; }
312 Register scratch2() const { return registers_[3]; }
313 Register scratch3() const { return registers_[4]; }
314
315 // Calling convention between indexed store IC and handler.
316 Register transition_map() const { return scratch1(); }
317
318 static Register* GetCallingConvention(Code::Kind);
319 static Register* load_calling_convention();
320 static Register* store_calling_convention();
321 static Register* keyed_store_calling_convention();
322
323 Register* registers_;
324
325 static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
326
327 Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
328 Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
329
330 private:
331 Code::Kind kind_;
332 CacheHolderFlag cache_holder_;
333
334 Isolate* isolate_;
335 const ExtraICState extra_ic_state_;
336 MacroAssembler masm_;
337 };
338
339
340 class PropertyICCompiler : public PropertyAccessCompiler {
341 public:
342 PropertyICCompiler(Isolate* isolate, Code::Kind kind,
343 ExtraICState extra_ic_state = kNoExtraICState,
344 CacheHolderFlag cache_holder = kCacheOnReceiver)
345 : PropertyAccessCompiler(isolate, kind, extra_ic_state, cache_holder) {}
346
347 static Handle<Code> Find(Handle<Name> name, Handle<Map> stub_holder_map,
348 Code::Kind kind,
349 ExtraICState extra_state = kNoExtraICState,
350 CacheHolderFlag cache_holder = kCacheOnReceiver);
288 351
289 Handle<Code> CompileLoadInitialize(Code::Flags flags); 352 Handle<Code> CompileLoadInitialize(Code::Flags flags);
290 Handle<Code> CompileLoadPreMonomorphic(Code::Flags flags); 353 Handle<Code> CompileLoadPreMonomorphic(Code::Flags flags);
291 Handle<Code> CompileLoadMegamorphic(Code::Flags flags); 354 Handle<Code> CompileLoadMegamorphic(Code::Flags flags);
292
293 Handle<Code> CompileStoreInitialize(Code::Flags flags); 355 Handle<Code> CompileStoreInitialize(Code::Flags flags);
294 Handle<Code> CompileStorePreMonomorphic(Code::Flags flags); 356 Handle<Code> CompileStorePreMonomorphic(Code::Flags flags);
295 Handle<Code> CompileStoreGeneric(Code::Flags flags); 357 Handle<Code> CompileStoreGeneric(Code::Flags flags);
296 Handle<Code> CompileStoreMegamorphic(Code::Flags flags); 358 Handle<Code> CompileStoreMegamorphic(Code::Flags flags);
297 359
298 // Static functions for generating parts of stubs. 360 Handle<Code> CompileMonomorphic(Handle<HeapType> type, Handle<Code> handler,
299 static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 361 Handle<Name> name, IcCheckType check);
300 int index, 362
301 Register prototype); 363 Handle<Code> CompilePolymorphic(TypeHandleList* types,
364 CodeHandleList* handlers, Handle<Name> name,
365 Code::StubType type, IcCheckType check);
366
367 Handle<Code> CompileIndexedStoreMonomorphic(Handle<Map> receiver_map,
368 KeyedAccessStoreMode store_mode);
369 Handle<Code> CompileIndexedStorePolymorphic(MapHandleList* receiver_maps,
370 KeyedAccessStoreMode store_mode);
371
372 private:
373 bool IncludesNumberType(TypeHandleList* types);
374
375 Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name,
376 InlineCacheState state = MONOMORPHIC);
377
378 Logger::LogEventsAndTags log_kind(Handle<Code> code) {
379 if (kind() == Code::LOAD_IC) {
380 return code->ic_state() == MONOMORPHIC ? Logger::LOAD_IC_TAG
381 : Logger::LOAD_POLYMORPHIC_IC_TAG;
382 } else if (kind() == Code::KEYED_LOAD_IC) {
383 return code->ic_state() == MONOMORPHIC
384 ? Logger::KEYED_LOAD_IC_TAG
385 : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
386 } else if (kind() == Code::STORE_IC) {
387 return code->ic_state() == MONOMORPHIC ? Logger::STORE_IC_TAG
388 : Logger::STORE_POLYMORPHIC_IC_TAG;
389 } else {
390 ASSERT_EQ(Code::KEYED_STORE_IC, kind());
391 return code->ic_state() == MONOMORPHIC
392 ? Logger::KEYED_STORE_IC_TAG
393 : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
394 }
395 }
396
397 Handle<Code> CompileIndexedStorePolymorphic(MapHandleList* receiver_maps,
398 CodeHandleList* handler_stubs,
399 MapHandleList* transitioned_maps);
400 };
401
402
403 class PropertyHandlerCompiler : public PropertyAccessCompiler {
404 public:
405 static Handle<Code> Find(Handle<Name> name, Handle<Map> map, Code::Kind kind,
406 CacheHolderFlag cache_holder, Code::StubType type);
407
408 protected:
409 PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
410 ExtraICState extra_ic_state,
411 CacheHolderFlag cache_holder)
412 : PropertyAccessCompiler(isolate, kind, extra_ic_state, cache_holder) {}
413
414 virtual ~PropertyHandlerCompiler() {}
415
416 virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg,
417 Handle<JSObject> holder, Handle<Name> name,
418 Label* miss) {
419 UNREACHABLE();
420 return receiver();
421 }
422
423 virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
424
425 Register Frontend(Handle<HeapType> type, Register object_reg,
426 Handle<JSObject> holder, Handle<Name> name);
427
428 // TODO(verwaest): Make non-static.
429 static void GenerateFastApiCall(MacroAssembler* masm,
430 const CallOptimization& optimization,
431 Handle<Map> receiver_map, Register receiver,
432 Register scratch, bool is_store, int argc,
433 Register* values);
302 434
303 // Helper function used to check that the dictionary doesn't contain 435 // Helper function used to check that the dictionary doesn't contain
304 // the property. This function may return false negatives, so miss_label 436 // the property. This function may return false negatives, so miss_label
305 // must always call a backup property check that is complete. 437 // must always call a backup property check that is complete.
306 // This function is safe to call if the receiver has fast properties. 438 // This function is safe to call if the receiver has fast properties.
307 // Name must be unique and receiver must be a heap object. 439 // Name must be unique and receiver must be a heap object.
308 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, 440 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
309 Label* miss_label, 441 Label* miss_label,
310 Register receiver, 442 Register receiver,
311 Handle<Name> name, 443 Handle<Name> name,
312 Register r0, 444 Register r0,
313 Register r1); 445 Register r1);
314 446
315 // Generates prototype loading code that uses the objects from the
316 // context we were in when this function was called. If the context
317 // has changed, a jump to miss is performed. This ties the generated
318 // code to a particular context and so must not be used in cases
319 // where the generated code is not allowed to have references to
320 // objects from a context.
321 static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
322 int index,
323 Register prototype,
324 Label* miss);
325
326 static void GenerateFastPropertyLoad(MacroAssembler* masm,
327 Register dst,
328 Register src,
329 bool inobject,
330 int index,
331 Representation representation);
332
333 static void GenerateLoadArrayLength(MacroAssembler* masm,
334 Register receiver,
335 Register scratch,
336 Label* miss_label);
337
338 static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
339 Register receiver,
340 Register scratch1,
341 Register scratch2,
342 Label* miss_label);
343
344 // Generate code to check that a global property cell is empty. Create 447 // Generate code to check that a global property cell is empty. Create
345 // the property cell at compilation time if no cell exists for the 448 // the property cell at compilation time if no cell exists for the
346 // property. 449 // property.
347 static void GenerateCheckPropertyCell(MacroAssembler* masm, 450 static void GenerateCheckPropertyCell(MacroAssembler* masm,
348 Handle<JSGlobalObject> global, 451 Handle<JSGlobalObject> global,
349 Handle<Name> name, 452 Handle<Name> name,
350 Register scratch, 453 Register scratch,
351 Label* miss); 454 Label* miss);
352 455
353 static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
354
355 // Generates code that verifies that the property holder has not changed 456 // Generates code that verifies that the property holder has not changed
356 // (checking maps of objects in the prototype chain for fast and global 457 // (checking maps of objects in the prototype chain for fast and global
357 // objects or doing negative lookup for slow objects, ensures that the 458 // objects or doing negative lookup for slow objects, ensures that the
358 // property cells for global objects are still empty) and checks that the map 459 // property cells for global objects are still empty) and checks that the map
359 // of the holder has not changed. If necessary the function also generates 460 // of the holder has not changed. If necessary the function also generates
360 // code for security check in case of global object holders. Helps to make 461 // code for security check in case of global object holders. Helps to make
361 // sure that the current IC is still valid. 462 // sure that the current IC is still valid.
362 // 463 //
363 // The scratch and holder registers are always clobbered, but the object 464 // The scratch and holder registers are always clobbered, but the object
364 // register is only clobbered if it the same as the holder register. The 465 // register is only clobbered if it the same as the holder register. The
365 // function returns a register containing the holder - either object_reg or 466 // function returns a register containing the holder - either object_reg or
366 // holder_reg. 467 // holder_reg.
367 Register CheckPrototypes(Handle<HeapType> type, 468 Register CheckPrototypes(Handle<HeapType> type,
368 Register object_reg, 469 Register object_reg,
369 Handle<JSObject> holder, 470 Handle<JSObject> holder,
370 Register holder_reg, 471 Register holder_reg,
371 Register scratch1, 472 Register scratch1,
372 Register scratch2, 473 Register scratch2,
373 Handle<Name> name, 474 Handle<Name> name,
374 Label* miss, 475 Label* miss,
375 PrototypeCheckType check = CHECK_ALL_MAPS); 476 PrototypeCheckType check = CHECK_ALL_MAPS);
376 477
377 static void GenerateFastApiCall(MacroAssembler* masm, 478 Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
378 const CallOptimization& optimization,
379 Handle<Map> receiver_map,
380 Register receiver,
381 Register scratch,
382 bool is_store,
383 int argc,
384 Register* values);
385
386 protected:
387 Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
388 Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
389
390 ExtraICState extra_state() { return extra_ic_state_; }
391
392 MacroAssembler* masm() { return &masm_; }
393
394 static void LookupPostInterceptor(Handle<JSObject> holder,
395 Handle<Name> name,
396 LookupResult* lookup);
397
398 Isolate* isolate() { return isolate_; }
399 Heap* heap() { return isolate()->heap(); }
400 Factory* factory() { return isolate()->factory(); }
401
402 static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
403
404 private:
405 Isolate* isolate_;
406 const ExtraICState extra_ic_state_;
407 MacroAssembler masm_;
408 }; 479 };
409 480
410 481
411 enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS }; 482 class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
483 public:
484 NamedLoadHandlerCompiler(Isolate* isolate, Code::Kind kind = Code::LOAD_IC,
485 ExtraICState extra_ic_state = kNoExtraICState,
486 CacheHolderFlag cache_holder = kCacheOnReceiver)
487 : PropertyHandlerCompiler(isolate, kind, extra_ic_state, cache_holder) {}
412 488
413 489 virtual ~NamedLoadHandlerCompiler() {}
414 class BaseLoadStoreStubCompiler: public StubCompiler {
415 public:
416 BaseLoadStoreStubCompiler(Isolate* isolate, Code::Kind kind,
417 ExtraICState extra_ic_state = kNoExtraICState,
418 CacheHolderFlag cache_holder = kCacheOnReceiver)
419 : StubCompiler(isolate, extra_ic_state),
420 kind_(kind),
421 cache_holder_(cache_holder) {
422 InitializeRegisters();
423 }
424 virtual ~BaseLoadStoreStubCompiler() { }
425
426 Handle<Code> CompileMonomorphicIC(Handle<HeapType> type,
427 Handle<Code> handler,
428 Handle<Name> name);
429
430 Handle<Code> CompilePolymorphicIC(TypeHandleList* types,
431 CodeHandleList* handlers,
432 Handle<Name> name,
433 Code::StubType type,
434 IcCheckType check);
435
436 static Builtins::Name MissBuiltin(Code::Kind kind) {
437 switch (kind) {
438 case Code::LOAD_IC: return Builtins::kLoadIC_Miss;
439 case Code::STORE_IC: return Builtins::kStoreIC_Miss;
440 case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss;
441 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss;
442 default: UNREACHABLE();
443 }
444 return Builtins::kLoadIC_Miss;
445 }
446
447 protected:
448 virtual Register HandlerFrontendHeader(Handle<HeapType> type,
449 Register object_reg,
450 Handle<JSObject> holder,
451 Handle<Name> name,
452 Label* miss) = 0;
453
454 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss) = 0;
455
456 Register HandlerFrontend(Handle<HeapType> type,
457 Register object_reg,
458 Handle<JSObject> holder,
459 Handle<Name> name);
460
461 Handle<Code> GetCode(Code::Kind kind,
462 Code::StubType type,
463 Handle<Name> name);
464
465 Handle<Code> GetICCode(Code::Kind kind,
466 Code::StubType type,
467 Handle<Name> name,
468 InlineCacheState state = MONOMORPHIC);
469 Code::Kind kind() { return kind_; }
470
471 Logger::LogEventsAndTags log_kind(Handle<Code> code) {
472 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
473 if (kind_ == Code::LOAD_IC) {
474 return code->ic_state() == MONOMORPHIC
475 ? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
476 } else if (kind_ == Code::KEYED_LOAD_IC) {
477 return code->ic_state() == MONOMORPHIC
478 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
479 } else if (kind_ == Code::STORE_IC) {
480 return code->ic_state() == MONOMORPHIC
481 ? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG;
482 } else {
483 return code->ic_state() == MONOMORPHIC
484 ? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
485 }
486 }
487
488 Register receiver() { return registers_[0]; }
489 Register name() { return registers_[1]; }
490 Register scratch1() { return registers_[2]; }
491 Register scratch2() { return registers_[3]; }
492 Register scratch3() { return registers_[4]; }
493
494 void InitializeRegisters();
495
496 bool IncludesNumberType(TypeHandleList* types);
497
498 Code::Kind kind_;
499 CacheHolderFlag cache_holder_;
500 Register* registers_;
501 };
502
503
504 class LoadStubCompiler: public BaseLoadStoreStubCompiler {
505 public:
506 LoadStubCompiler(Isolate* isolate, Code::Kind kind = Code::LOAD_IC,
507 ExtraICState extra_ic_state = kNoExtraICState,
508 CacheHolderFlag cache_holder = kCacheOnReceiver)
509 : BaseLoadStoreStubCompiler(isolate, kind, extra_ic_state, cache_holder) {
510 }
511 virtual ~LoadStubCompiler() { }
512 static Register* registers();
513 490
514 Handle<Code> CompileLoadField(Handle<HeapType> type, 491 Handle<Code> CompileLoadField(Handle<HeapType> type,
515 Handle<JSObject> holder, 492 Handle<JSObject> holder,
516 Handle<Name> name, 493 Handle<Name> name,
517 FieldIndex index, 494 FieldIndex index,
518 Representation representation); 495 Representation representation);
519 496
520 Handle<Code> CompileLoadCallback(Handle<HeapType> type, 497 Handle<Code> CompileLoadCallback(Handle<HeapType> type,
521 Handle<JSObject> holder, 498 Handle<JSObject> holder,
522 Handle<Name> name, 499 Handle<Name> name,
(...skipping 11 matching lines...) Expand all
534 511
535 Handle<Code> CompileLoadInterceptor(Handle<HeapType> type, 512 Handle<Code> CompileLoadInterceptor(Handle<HeapType> type,
536 Handle<JSObject> holder, 513 Handle<JSObject> holder,
537 Handle<Name> name); 514 Handle<Name> name);
538 515
539 Handle<Code> CompileLoadViaGetter(Handle<HeapType> type, 516 Handle<Code> CompileLoadViaGetter(Handle<HeapType> type,
540 Handle<JSObject> holder, 517 Handle<JSObject> holder,
541 Handle<Name> name, 518 Handle<Name> name,
542 Handle<JSFunction> getter); 519 Handle<JSFunction> getter);
543 520
544 static void GenerateLoadViaGetter(MacroAssembler* masm,
545 Handle<HeapType> type,
546 Register receiver,
547 Handle<JSFunction> getter);
548
549 static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
550 GenerateLoadViaGetter(
551 masm, Handle<HeapType>::null(), no_reg, Handle<JSFunction>());
552 }
553
554 Handle<Code> CompileLoadNonexistent(Handle<HeapType> type, 521 Handle<Code> CompileLoadNonexistent(Handle<HeapType> type,
555 Handle<JSObject> last, 522 Handle<JSObject> last,
556 Handle<Name> name); 523 Handle<Name> name);
557 524
558 Handle<Code> CompileLoadGlobal(Handle<HeapType> type, 525 Handle<Code> CompileLoadGlobal(Handle<HeapType> type,
559 Handle<GlobalObject> holder, 526 Handle<GlobalObject> holder,
560 Handle<PropertyCell> cell, 527 Handle<PropertyCell> cell,
561 Handle<Name> name, 528 Handle<Name> name,
562 bool is_dont_delete); 529 bool is_dont_delete);
563 530
564 protected: 531 static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
565 ContextualMode contextual_mode() { 532 Register receiver,
566 return LoadIC::GetContextualMode(extra_state()); 533 Handle<JSFunction> getter);
534
535 static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
536 GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg,
537 Handle<JSFunction>());
567 } 538 }
568 539
569 virtual Register HandlerFrontendHeader(Handle<HeapType> type, 540 static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
570 Register object_reg, 541 Register receiver,
571 Handle<JSObject> holder, 542 Register scratch1,
572 Handle<Name> name, 543 Register scratch2,
573 Label* miss); 544 Label* miss_label);
574 545
575 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss); 546 protected:
547 virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg,
548 Handle<JSObject> holder, Handle<Name> name,
549 Label* miss);
576 550
577 Register CallbackHandlerFrontend(Handle<HeapType> type, 551 virtual void FrontendFooter(Handle<Name> name, Label* miss);
578 Register object_reg, 552
579 Handle<JSObject> holder, 553 private:
580 Handle<Name> name, 554 Register CallbackFrontend(Handle<HeapType> type, Register object_reg,
581 Handle<Object> callback); 555 Handle<JSObject> holder, Handle<Name> name,
582 void NonexistentHandlerFrontend(Handle<HeapType> type, 556 Handle<Object> callback);
583 Handle<JSObject> last, 557 void NonexistentFrontend(Handle<HeapType> type, Handle<JSObject> last,
584 Handle<Name> name); 558 Handle<Name> name);
585 559
586 void GenerateLoadField(Register reg, 560 void GenerateLoadField(Register reg,
587 Handle<JSObject> holder, 561 Handle<JSObject> holder,
588 FieldIndex field, 562 FieldIndex field,
589 Representation representation); 563 Representation representation);
590 void GenerateLoadConstant(Handle<Object> value); 564 void GenerateLoadConstant(Handle<Object> value);
591 void GenerateLoadCallback(Register reg, 565 void GenerateLoadCallback(Register reg,
592 Handle<ExecutableAccessorInfo> callback); 566 Handle<ExecutableAccessorInfo> callback);
593 void GenerateLoadCallback(const CallOptimization& call_optimization, 567 void GenerateLoadCallback(const CallOptimization& call_optimization,
594 Handle<Map> receiver_map); 568 Handle<Map> receiver_map);
595 void GenerateLoadInterceptor(Register holder_reg, 569 void GenerateLoadInterceptor(Register holder_reg,
596 Handle<Object> object, 570 Handle<Object> object,
597 Handle<JSObject> holder, 571 Handle<JSObject> holder,
598 LookupResult* lookup, 572 LookupResult* lookup,
599 Handle<Name> name); 573 Handle<Name> name);
600 void GenerateLoadPostInterceptor(Register reg, 574 void GenerateLoadPostInterceptor(Register reg,
601 Handle<JSObject> interceptor_holder, 575 Handle<JSObject> interceptor_holder,
602 Handle<Name> name, 576 Handle<Name> name,
603 LookupResult* lookup); 577 LookupResult* lookup);
604 578
605 private: 579 // Generates prototype loading code that uses the objects from the
580 // context we were in when this function was called. If the context
581 // has changed, a jump to miss is performed. This ties the generated
582 // code to a particular context and so must not be used in cases
583 // where the generated code is not allowed to have references to
584 // objects from a context.
585 static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
586 int index,
587 Register prototype,
588 Label* miss);
589
590
606 Register scratch4() { return registers_[5]; } 591 Register scratch4() { return registers_[5]; }
607 friend class BaseLoadStoreStubCompiler;
608 }; 592 };
609 593
610 594
611 class KeyedLoadStubCompiler : public StubCompiler { 595 class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
612 public: 596 public:
613 KeyedLoadStubCompiler(Isolate* isolate, 597 NamedStoreHandlerCompiler(Isolate* isolate, Code::Kind kind = Code::STORE_IC)
614 ExtraICState extra_ic_state = kNoExtraICState) 598 // Handlers do not use strict mode.
615 : StubCompiler(isolate, extra_ic_state) { 599 : PropertyHandlerCompiler(isolate, kind, kNoExtraICState,
616 registers_ = LoadStubCompiler::registers(); 600 kCacheOnReceiver) {}
617 }
618 601
619 Handle<Code> CompileLoadElement(Handle<Map> receiver_map); 602 virtual ~NamedStoreHandlerCompiler() {}
620
621 void CompileElementHandlers(MapHandleList* receiver_maps,
622 CodeHandleList* handlers);
623
624 static void GenerateLoadDictionaryElement(MacroAssembler* masm);
625
626 Register receiver() { return registers_[0]; }
627 Register name() { return registers_[1]; }
628 Register scratch1() { return registers_[2]; }
629 Register scratch2() { return registers_[3]; }
630 Register scratch3() { return registers_[4]; }
631
632 private:
633 static Register* registers();
634 Register* registers_;
635 };
636
637
638 class StoreStubCompiler: public BaseLoadStoreStubCompiler {
639 public:
640 StoreStubCompiler(Isolate* isolate,
641 ExtraICState extra_ic_state,
642 Code::Kind kind = Code::STORE_IC)
643 : BaseLoadStoreStubCompiler(isolate, kind, extra_ic_state) {}
644
645 virtual ~StoreStubCompiler() { }
646 603
647 Handle<Code> CompileStoreTransition(Handle<JSObject> object, 604 Handle<Code> CompileStoreTransition(Handle<JSObject> object,
648 LookupResult* lookup, 605 LookupResult* lookup,
649 Handle<Map> transition, 606 Handle<Map> transition,
650 Handle<Name> name); 607 Handle<Name> name);
651 608
652 Handle<Code> CompileStoreField(Handle<JSObject> object, 609 Handle<Code> CompileStoreField(Handle<JSObject> object,
653 LookupResult* lookup, 610 LookupResult* lookup,
654 Handle<Name> name); 611 Handle<Name> name);
655 612
656 Handle<Code> CompileStoreArrayLength(Handle<JSObject> object, 613 Handle<Code> CompileStoreArrayLength(Handle<JSObject> object,
657 LookupResult* lookup, 614 LookupResult* lookup,
658 Handle<Name> name); 615 Handle<Name> name);
659 616
617 Handle<Code> CompileStoreCallback(Handle<JSObject> object,
618 Handle<JSObject> holder, Handle<Name> name,
619 Handle<ExecutableAccessorInfo> callback);
620
621 Handle<Code> CompileStoreCallback(Handle<JSObject> object,
622 Handle<JSObject> holder, Handle<Name> name,
623 const CallOptimization& call_optimization);
624
625 Handle<Code> CompileStoreViaSetter(Handle<JSObject> object,
626 Handle<JSObject> holder, Handle<Name> name,
627 Handle<JSFunction> setter);
628
629 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
630 Handle<Name> name);
631
632
633 static void GenerateStoreViaSetter(MacroAssembler* masm,
634 Handle<HeapType> type, Register receiver,
635 Handle<JSFunction> setter);
636
637 static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
638 GenerateStoreViaSetter(masm, Handle<HeapType>::null(), no_reg,
639 Handle<JSFunction>());
640 }
641
642 protected:
643 virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg,
644 Handle<JSObject> holder, Handle<Name> name,
645 Label* miss);
646
647 virtual void FrontendFooter(Handle<Name> name, Label* miss);
648 void GenerateRestoreName(MacroAssembler* masm, Label* label,
649 Handle<Name> name);
650
651 private:
660 void GenerateStoreArrayLength(); 652 void GenerateStoreArrayLength();
661 653
662 void GenerateNegativeHolderLookup(MacroAssembler* masm, 654 void GenerateNegativeHolderLookup(MacroAssembler* masm,
663 Handle<JSObject> holder, 655 Handle<JSObject> holder,
664 Register holder_reg, 656 Register holder_reg,
665 Handle<Name> name, 657 Handle<Name> name,
666 Label* miss); 658 Label* miss);
667 659
668 void GenerateStoreTransition(MacroAssembler* masm, 660 void GenerateStoreTransition(MacroAssembler* masm,
669 Handle<JSObject> object, 661 Handle<JSObject> object,
(...skipping 12 matching lines...) Expand all
682 void GenerateStoreField(MacroAssembler* masm, 674 void GenerateStoreField(MacroAssembler* masm,
683 Handle<JSObject> object, 675 Handle<JSObject> object,
684 LookupResult* lookup, 676 LookupResult* lookup,
685 Register receiver_reg, 677 Register receiver_reg,
686 Register name_reg, 678 Register name_reg,
687 Register value_reg, 679 Register value_reg,
688 Register scratch1, 680 Register scratch1,
689 Register scratch2, 681 Register scratch2,
690 Label* miss_label); 682 Label* miss_label);
691 683
692 Handle<Code> CompileStoreCallback(Handle<JSObject> object,
693 Handle<JSObject> holder,
694 Handle<Name> name,
695 Handle<ExecutableAccessorInfo> callback);
696
697 Handle<Code> CompileStoreCallback(Handle<JSObject> object,
698 Handle<JSObject> holder,
699 Handle<Name> name,
700 const CallOptimization& call_optimization);
701
702 static void GenerateStoreViaSetter(MacroAssembler* masm,
703 Handle<HeapType> type,
704 Register receiver,
705 Handle<JSFunction> setter);
706
707 static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
708 GenerateStoreViaSetter(
709 masm, Handle<HeapType>::null(), no_reg, Handle<JSFunction>());
710 }
711
712 Handle<Code> CompileStoreViaSetter(Handle<JSObject> object,
713 Handle<JSObject> holder,
714 Handle<Name> name,
715 Handle<JSFunction> setter);
716
717 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
718 Handle<Name> name);
719
720 static Builtins::Name SlowBuiltin(Code::Kind kind) { 684 static Builtins::Name SlowBuiltin(Code::Kind kind) {
721 switch (kind) { 685 switch (kind) {
722 case Code::STORE_IC: return Builtins::kStoreIC_Slow; 686 case Code::STORE_IC: return Builtins::kStoreIC_Slow;
723 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Slow; 687 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Slow;
724 default: UNREACHABLE(); 688 default: UNREACHABLE();
725 } 689 }
726 return Builtins::kStoreIC_Slow; 690 return Builtins::kStoreIC_Slow;
727 } 691 }
728 692
729 protected:
730 virtual Register HandlerFrontendHeader(Handle<HeapType> type,
731 Register object_reg,
732 Handle<JSObject> holder,
733 Handle<Name> name,
734 Label* miss);
735
736 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss);
737 void GenerateRestoreName(MacroAssembler* masm,
738 Label* label,
739 Handle<Name> name);
740
741 private:
742 static Register* registers();
743 static Register value(); 693 static Register value();
744 friend class BaseLoadStoreStubCompiler;
745 }; 694 };
746 695
747 696
748 class KeyedStoreStubCompiler: public StoreStubCompiler { 697 class IndexedHandlerCompiler : public PropertyHandlerCompiler {
749 public: 698 public:
750 KeyedStoreStubCompiler(Isolate* isolate, 699 IndexedHandlerCompiler(Isolate* isolate,
751 ExtraICState extra_ic_state) 700 ExtraICState extra_ic_state = kNoExtraICState)
752 : StoreStubCompiler(isolate, extra_ic_state, Code::KEYED_STORE_IC) {} 701 : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC, extra_ic_state,
702 kCacheOnReceiver) {}
753 703
754 Handle<Code> CompileStoreElement(Handle<Map> receiver_map); 704 virtual ~IndexedHandlerCompiler() {}
755 705
756 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps, 706 void CompileElementHandlers(MapHandleList* receiver_maps,
757 CodeHandleList* handler_stubs, 707 CodeHandleList* handlers);
758 MapHandleList* transitioned_maps);
759 708
760 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps); 709 static void GenerateLoadDictionaryElement(MacroAssembler* masm);
761
762 static void GenerateStoreDictionaryElement(MacroAssembler* masm); 710 static void GenerateStoreDictionaryElement(MacroAssembler* masm);
763
764 private:
765 static Register* registers();
766
767 KeyedAccessStoreMode store_mode() {
768 return KeyedStoreIC::GetKeyedAccessStoreMode(extra_state());
769 }
770
771 Register transition_map() { return scratch1(); }
772
773 friend class BaseLoadStoreStubCompiler;
774 }; 711 };
775 712
776 713
777 // Holds information about possible function call optimizations. 714 // Holds information about possible function call optimizations.
778 class CallOptimization BASE_EMBEDDED { 715 class CallOptimization BASE_EMBEDDED {
779 public: 716 public:
780 explicit CallOptimization(LookupResult* lookup); 717 explicit CallOptimization(LookupResult* lookup);
781 718
782 explicit CallOptimization(Handle<JSFunction> function); 719 explicit CallOptimization(Handle<JSFunction> function);
783 720
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 Handle<JSFunction> constant_function_; 764 Handle<JSFunction> constant_function_;
828 bool is_simple_api_call_; 765 bool is_simple_api_call_;
829 Handle<FunctionTemplateInfo> expected_receiver_type_; 766 Handle<FunctionTemplateInfo> expected_receiver_type_;
830 Handle<CallHandlerInfo> api_call_info_; 767 Handle<CallHandlerInfo> api_call_info_;
831 }; 768 };
832 769
833 770
834 } } // namespace v8::internal 771 } } // namespace v8::internal
835 772
836 #endif // V8_STUB_CACHE_H_ 773 #endif // V8_STUB_CACHE_H_
OLDNEW
« src/ia32/stub-cache-ia32.cc ('K') | « src/ic.cc ('k') | src/stub-cache.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698