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

Side by Side Diff: src/ic.h

Issue 11953025: Move polymorphic stub computation and compilation to stub cache (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 125
126 // Determines which map must be used for keeping the code stub. 126 // Determines which map must be used for keeping the code stub.
127 // These methods should not be called with undefined or null. 127 // These methods should not be called with undefined or null.
128 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object, 128 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object,
129 JSObject* holder); 129 JSObject* holder);
130 static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, 130 static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object,
131 JSObject* holder); 131 JSObject* holder);
132 static inline JSObject* GetCodeCacheHolder(Object* object, 132 static inline JSObject* GetCodeCacheHolder(Object* object,
133 InlineCacheHolderFlag holder); 133 InlineCacheHolderFlag holder);
134 134
135 MUST_USE_RESULT MaybeObject* Load(State state,
136 Handle<Object> object,
137 Handle<String> name);
138
139 MUST_USE_RESULT MaybeObject* Store(
140 State state,
141 StrictModeFlag strict_mode,
142 Handle<Object> object,
143 Handle<String> name,
144 Handle<Object> value,
145 JSReceiver::StoreFromKeyed store_mode =
146 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
147
148 protected: 135 protected:
149 virtual Handle<Code> pre_monomorphic_stub() {
150 UNREACHABLE();
151 return Handle<Code>::null();
152 }
153 virtual Handle<Code> megamorphic_stub() {
154 UNREACHABLE();
155 return Handle<Code>::null();
156 }
157 virtual Handle<Code> megamorphic_stub_strict() {
158 UNREACHABLE();
159 return Handle<Code>::null();
160 }
161 virtual Handle<Code> generic_stub() const {
162 UNREACHABLE();
163 return Handle<Code>::null();
164 }
165 virtual Code::Kind kind() const {
166 UNREACHABLE();
167 return Code::STUB;
168 }
169 virtual Handle<Code> global_proxy_stub() {
170 UNREACHABLE();
171 return Handle<Code>::null();
172 }
173 virtual Handle<Code> global_proxy_stub_strict() {
174 UNREACHABLE();
175 return Handle<Code>::null();
176 }
177
178 virtual void UpdateLoadCaches(LookupResult* lookup,
179 State state,
180 Handle<Object> object,
181 Handle<String> name) {
182 UNREACHABLE();
183 }
184 virtual void UpdateStoreCaches(LookupResult* lookup,
185 State state,
186 StrictModeFlag strict_mode,
187 Handle<JSObject> receiver,
188 Handle<String> name,
189 Handle<Object> value) {
190 UNREACHABLE();
191 }
192 Address fp() const { return fp_; } 136 Address fp() const { return fp_; }
193 Address pc() const { return *pc_address_; } 137 Address pc() const { return *pc_address_; }
194 Isolate* isolate() const { return isolate_; } 138 Isolate* isolate() const { return isolate_; }
195 139
196 #ifdef ENABLE_DEBUGGER_SUPPORT 140 #ifdef ENABLE_DEBUGGER_SUPPORT
197 // Computes the address in the original code when the code running is 141 // Computes the address in the original code when the code running is
198 // containing break points (calls to DebugBreakXXX builtins). 142 // containing break points (calls to DebugBreakXXX builtins).
199 Address OriginalCodeAddress() const; 143 Address OriginalCodeAddress() const;
200 #endif 144 #endif
201 145
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 313
370 static void GenerateMegamorphic(MacroAssembler* masm, int argc); 314 static void GenerateMegamorphic(MacroAssembler* masm, int argc);
371 static void GenerateNormal(MacroAssembler* masm, int argc); 315 static void GenerateNormal(MacroAssembler* masm, int argc);
372 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); 316 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
373 }; 317 };
374 318
375 319
376 class LoadIC: public IC { 320 class LoadIC: public IC {
377 public: 321 public:
378 explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { 322 explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
379 ASSERT(target()->is_load_stub()); 323 ASSERT(target()->is_load_stub() || target()->is_keyed_load_stub());
380 } 324 }
381 325
382 // Code generator routines. 326 // Code generator routines.
383 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 327 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
384 static void GeneratePreMonomorphic(MacroAssembler* masm) { 328 static void GeneratePreMonomorphic(MacroAssembler* masm) {
385 GenerateMiss(masm); 329 GenerateMiss(masm);
386 } 330 }
387 static void GenerateMiss(MacroAssembler* masm); 331 static void GenerateMiss(MacroAssembler* masm);
388 static void GenerateMegamorphic(MacroAssembler* masm); 332 static void GenerateMegamorphic(MacroAssembler* masm);
389 static void GenerateNormal(MacroAssembler* masm); 333 static void GenerateNormal(MacroAssembler* masm);
390 334
391 // Specialized code generator routines. 335 // Specialized code generator routines.
392 static void GenerateArrayLength(MacroAssembler* masm); 336 static void GenerateArrayLength(MacroAssembler* masm);
393 static void GenerateFunctionPrototype(MacroAssembler* masm); 337 static void GenerateFunctionPrototype(MacroAssembler* masm);
394 338
339 MUST_USE_RESULT MaybeObject* Load(State state,
340 Handle<Object> object,
341 Handle<String> name);
342
395 protected: 343 protected:
396 virtual Code::Kind kind() const { return Code::LOAD_IC; } 344 virtual Code::Kind kind() const { return Code::LOAD_IC; }
397 345
346 virtual Handle<Code> generic_stub() const {
347 UNREACHABLE();
348 return Handle<Code>::null();
349 }
350
398 virtual Handle<Code> megamorphic_stub() { 351 virtual Handle<Code> megamorphic_stub() {
399 return isolate()->builtins()->LoadIC_Megamorphic(); 352 return isolate()->builtins()->LoadIC_Megamorphic();
400 } 353 }
401 354
402 // Update the inline cache and the global stub cache based on the 355 // Update the inline cache and the global stub cache based on the
403 // lookup result. 356 // lookup result.
404 virtual void UpdateLoadCaches(LookupResult* lookup, 357 virtual void UpdateLoadCaches(LookupResult* lookup,
405 State state, 358 State state,
406 Handle<Object> object, 359 Handle<Object> object,
407 Handle<String> name); 360 Handle<String> name);
408 361
409 private: 362 private:
410 // Stub accessors. 363 // Stub accessors.
411 static Handle<Code> initialize_stub() { 364 static Handle<Code> initialize_stub() {
412 return Isolate::Current()->builtins()->LoadIC_Initialize(); 365 return Isolate::Current()->builtins()->LoadIC_Initialize();
413 } 366 }
414 virtual Handle<Code> pre_monomorphic_stub() { 367 virtual Handle<Code> pre_monomorphic_stub() {
415 return isolate()->builtins()->LoadIC_PreMonomorphic(); 368 return isolate()->builtins()->LoadIC_PreMonomorphic();
416 } 369 }
417 370
418 static void Clear(Address address, Code* target); 371 static void Clear(Address address, Code* target);
419 372
420 friend class IC; 373 friend class IC;
421 }; 374 };
422 375
423 376
424 class KeyedIC: public IC {
425 public:
426 enum StubKind {
427 LOAD,
428 STORE_NO_TRANSITION,
429 STORE_TRANSITION_SMI_TO_OBJECT,
430 STORE_TRANSITION_SMI_TO_DOUBLE,
431 STORE_TRANSITION_DOUBLE_TO_OBJECT,
432 STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
433 STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
434 STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
435 STORE_AND_GROW_NO_TRANSITION,
436 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
437 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
438 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
439 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
440 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
441 STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT
442 };
443
444 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
445 STORE_NO_TRANSITION;
446 STATIC_ASSERT(kGrowICDelta ==
447 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
448 STORE_TRANSITION_SMI_TO_OBJECT);
449 STATIC_ASSERT(kGrowICDelta ==
450 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
451 STORE_TRANSITION_SMI_TO_DOUBLE);
452 STATIC_ASSERT(kGrowICDelta ==
453 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
454 STORE_TRANSITION_DOUBLE_TO_OBJECT);
455
456 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
457 virtual ~KeyedIC() {}
458
459 static inline KeyedAccessGrowMode GetGrowModeFromStubKind(
460 StubKind stub_kind) {
461 return (stub_kind >= STORE_AND_GROW_NO_TRANSITION)
462 ? ALLOW_JSARRAY_GROWTH
463 : DO_NOT_ALLOW_JSARRAY_GROWTH;
464 }
465
466 static inline StubKind GetGrowStubKind(StubKind stub_kind) {
467 ASSERT(stub_kind != LOAD);
468 if (stub_kind < STORE_AND_GROW_NO_TRANSITION) {
469 stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) +
470 kGrowICDelta);
471 }
472 return stub_kind;
473 }
474
475 virtual Handle<Code> GetElementStubWithoutMapCheck(
476 bool is_js_array,
477 ElementsKind elements_kind,
478 KeyedAccessGrowMode grow_mode) = 0;
479
480 protected:
481 virtual Handle<Code> string_stub() {
482 return Handle<Code>::null();
483 }
484
485 Handle<Code> ComputeStub(Handle<JSObject> receiver,
486 StubKind stub_kind,
487 StrictModeFlag strict_mode,
488 Handle<Code> default_stub);
489
490 virtual Handle<Code> ComputePolymorphicStub(
491 MapHandleList* receiver_maps,
492 StrictModeFlag strict_mode,
493 KeyedAccessGrowMode grow_mode) = 0;
494
495 Handle<Code> ComputeMonomorphicStubWithoutMapCheck(
496 Handle<Map> receiver_map,
497 StrictModeFlag strict_mode,
498 KeyedAccessGrowMode grow_mode);
499
500 private:
501 void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
502
503 Handle<Code> ComputeMonomorphicStub(Handle<Map> receiver_map,
504 StubKind stub_kind,
505 StrictModeFlag strict_mode,
506 Handle<Code> default_stub);
507
508 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
509 StubKind stub_kind);
510
511 static bool IsTransitionStubKind(StubKind stub_kind) {
512 return stub_kind > STORE_NO_TRANSITION &&
513 stub_kind != STORE_AND_GROW_NO_TRANSITION;
514 }
515
516 static bool IsGrowStubKind(StubKind stub_kind) {
517 return stub_kind >= STORE_AND_GROW_NO_TRANSITION;
518 }
519
520 static StubKind GetNoTransitionStubKind(StubKind stub_kind) {
521 if (!IsTransitionStubKind(stub_kind)) return stub_kind;
522 if (IsGrowStubKind(stub_kind)) return STORE_AND_GROW_NO_TRANSITION;
523 return STORE_NO_TRANSITION;
524 }
525 };
526
527
528 enum ICMissMode { 377 enum ICMissMode {
529 MISS_FORCE_GENERIC, 378 MISS_FORCE_GENERIC,
530 MISS 379 MISS
531 }; 380 };
532 381
533 382
534 class KeyedLoadIC: public KeyedIC { 383 class KeyedLoadIC: public LoadIC {
535 public: 384 public:
536 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { 385 explicit KeyedLoadIC(Isolate* isolate) : LoadIC(isolate) {
537 ASSERT(target()->is_keyed_load_stub()); 386 ASSERT(target()->is_keyed_load_stub());
538 } 387 }
539 388
540 MUST_USE_RESULT MaybeObject* Load(State state, 389 MUST_USE_RESULT MaybeObject* Load(State state,
541 Handle<Object> object, 390 Handle<Object> object,
542 Handle<Object> key, 391 Handle<Object> key,
543 ICMissMode force_generic); 392 ICMissMode force_generic);
544 393
545 // Code generator routines. 394 // Code generator routines.
546 static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic); 395 static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic);
547 static void GenerateRuntimeGetProperty(MacroAssembler* masm); 396 static void GenerateRuntimeGetProperty(MacroAssembler* masm);
548 static void GenerateInitialize(MacroAssembler* masm) { 397 static void GenerateInitialize(MacroAssembler* masm) {
549 GenerateMiss(masm, MISS); 398 GenerateMiss(masm, MISS);
550 } 399 }
551 static void GeneratePreMonomorphic(MacroAssembler* masm) { 400 static void GeneratePreMonomorphic(MacroAssembler* masm) {
552 GenerateMiss(masm, MISS); 401 GenerateMiss(masm, MISS);
553 } 402 }
554 static void GenerateGeneric(MacroAssembler* masm); 403 static void GenerateGeneric(MacroAssembler* masm);
555 static void GenerateString(MacroAssembler* masm); 404 static void GenerateString(MacroAssembler* masm);
556 static void GenerateIndexedInterceptor(MacroAssembler* masm); 405 static void GenerateIndexedInterceptor(MacroAssembler* masm);
557 static void GenerateNonStrictArguments(MacroAssembler* masm); 406 static void GenerateNonStrictArguments(MacroAssembler* masm);
558 407
559 // Bit mask to be tested against bit field for the cases when 408 // Bit mask to be tested against bit field for the cases when
560 // generic stub should go into slow case. 409 // generic stub should go into slow case.
561 // Access check is necessary explicitly since generic stub does not perform 410 // Access check is necessary explicitly since generic stub does not perform
562 // map checks. 411 // map checks.
563 static const int kSlowCaseBitFieldMask = 412 static const int kSlowCaseBitFieldMask =
564 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); 413 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
565 414
566 virtual Handle<Code> GetElementStubWithoutMapCheck(
567 bool is_js_array,
568 ElementsKind elements_kind,
569 KeyedAccessGrowMode grow_mode);
570
571 protected: 415 protected:
572 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } 416 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
573 417
418 Handle<Code> LoadElementStub(Handle<JSObject> receiver);
419
574 virtual Handle<Code> megamorphic_stub() { 420 virtual Handle<Code> megamorphic_stub() {
575 return isolate()->builtins()->KeyedLoadIC_Generic(); 421 return isolate()->builtins()->KeyedLoadIC_Generic();
576 } 422 }
577 virtual Handle<Code> generic_stub() const { 423 virtual Handle<Code> generic_stub() const {
578 return isolate()->builtins()->KeyedLoadIC_Generic(); 424 return isolate()->builtins()->KeyedLoadIC_Generic();
579 } 425 }
580 426
581 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
582 StrictModeFlag strict_mode,
583 KeyedAccessGrowMode grow_mode);
584
585 virtual Handle<Code> string_stub() {
586 return isolate()->builtins()->KeyedLoadIC_String();
587 }
588
589 // Update the inline cache. 427 // Update the inline cache.
590 virtual void UpdateLoadCaches(LookupResult* lookup, 428 virtual void UpdateLoadCaches(LookupResult* lookup,
591 State state, 429 State state,
592 Handle<Object> object, 430 Handle<Object> object,
593 Handle<String> name); 431 Handle<String> name);
594 432
595 private: 433 private:
596 // Stub accessors. 434 // Stub accessors.
597 static Handle<Code> initialize_stub() { 435 static Handle<Code> initialize_stub() {
598 return Isolate::Current()->builtins()->KeyedLoadIC_Initialize(); 436 return Isolate::Current()->builtins()->KeyedLoadIC_Initialize();
599 } 437 }
600 virtual Handle<Code> pre_monomorphic_stub() { 438 virtual Handle<Code> pre_monomorphic_stub() {
601 return isolate()->builtins()->KeyedLoadIC_PreMonomorphic(); 439 return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
602 } 440 }
603 Handle<Code> indexed_interceptor_stub() { 441 Handle<Code> indexed_interceptor_stub() {
604 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor(); 442 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
605 } 443 }
606 Handle<Code> non_strict_arguments_stub() { 444 Handle<Code> non_strict_arguments_stub() {
607 return isolate()->builtins()->KeyedLoadIC_NonStrictArguments(); 445 return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
608 } 446 }
447 Handle<Code> string_stub() {
448 return isolate()->builtins()->KeyedLoadIC_String();
449 }
609 450
610 static void Clear(Address address, Code* target); 451 static void Clear(Address address, Code* target);
611 452
612 friend class IC; 453 friend class IC;
613 }; 454 };
614 455
615 456
616 class StoreIC: public IC { 457 class StoreIC: public IC {
617 public: 458 public:
618 explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { 459 explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
619 ASSERT(target()->is_store_stub()); 460 ASSERT(target()->is_store_stub() || target()->is_keyed_store_stub());
620 } 461 }
621 462
622 // Code generators for stub routines. Only called once at startup. 463 // Code generators for stub routines. Only called once at startup.
623 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 464 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
624 static void GenerateMiss(MacroAssembler* masm); 465 static void GenerateMiss(MacroAssembler* masm);
625 static void GenerateMegamorphic(MacroAssembler* masm, 466 static void GenerateMegamorphic(MacroAssembler* masm,
626 StrictModeFlag strict_mode); 467 StrictModeFlag strict_mode);
627 static void GenerateArrayLength(MacroAssembler* masm); 468 static void GenerateArrayLength(MacroAssembler* masm);
628 static void GenerateNormal(MacroAssembler* masm); 469 static void GenerateNormal(MacroAssembler* masm);
629 static void GenerateGlobalProxy(MacroAssembler* masm, 470 static void GenerateGlobalProxy(MacroAssembler* masm,
630 StrictModeFlag strict_mode); 471 StrictModeFlag strict_mode);
631 472
473 MUST_USE_RESULT MaybeObject* Store(
474 State state,
475 StrictModeFlag strict_mode,
476 Handle<Object> object,
477 Handle<String> name,
478 Handle<Object> value,
479 JSReceiver::StoreFromKeyed store_mode =
480 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
481
632 protected: 482 protected:
633 virtual Code::Kind kind() const { return Code::STORE_IC; } 483 virtual Code::Kind kind() const { return Code::STORE_IC; }
634 virtual Handle<Code> megamorphic_stub() { 484 virtual Handle<Code> megamorphic_stub() {
635 return isolate()->builtins()->StoreIC_Megamorphic(); 485 return isolate()->builtins()->StoreIC_Megamorphic();
636 } 486 }
637 // Stub accessors. 487 // Stub accessors.
638 virtual Handle<Code> megamorphic_stub_strict() { 488 virtual Handle<Code> megamorphic_stub_strict() {
639 return isolate()->builtins()->StoreIC_Megamorphic_Strict(); 489 return isolate()->builtins()->StoreIC_Megamorphic_Strict();
640 } 490 }
641 virtual Handle<Code> global_proxy_stub() { 491 virtual Handle<Code> global_proxy_stub() {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 kCheckMap 530 kCheckMap
681 }; 531 };
682 532
683 533
684 enum KeyedStoreIncrementLength { 534 enum KeyedStoreIncrementLength {
685 kDontIncrementLength, 535 kDontIncrementLength,
686 kIncrementLength 536 kIncrementLength
687 }; 537 };
688 538
689 539
690 class KeyedStoreIC: public KeyedIC { 540 class KeyedStoreIC: public StoreIC {
691 public: 541 public:
692 explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) { 542 enum StubKind {
543 STORE_NO_TRANSITION,
544 STORE_TRANSITION_SMI_TO_OBJECT,
545 STORE_TRANSITION_SMI_TO_DOUBLE,
546 STORE_TRANSITION_DOUBLE_TO_OBJECT,
547 STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
548 STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
549 STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
550 STORE_AND_GROW_NO_TRANSITION,
551 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
552 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
553 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
554 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
555 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
556 STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT
557 };
558
559 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
560 STORE_NO_TRANSITION;
561 STATIC_ASSERT(kGrowICDelta ==
562 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
563 STORE_TRANSITION_SMI_TO_OBJECT);
564 STATIC_ASSERT(kGrowICDelta ==
565 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
566 STORE_TRANSITION_SMI_TO_DOUBLE);
567 STATIC_ASSERT(kGrowICDelta ==
568 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
569 STORE_TRANSITION_DOUBLE_TO_OBJECT);
570
571 static inline StubKind GetGrowStubKind(StubKind stub_kind) {
572 if (stub_kind < STORE_AND_GROW_NO_TRANSITION) {
573 stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) +
574 kGrowICDelta);
575 }
576 return stub_kind;
577 }
578
579 explicit KeyedStoreIC(Isolate* isolate) : StoreIC(isolate) {
693 ASSERT(target()->is_keyed_store_stub()); 580 ASSERT(target()->is_keyed_store_stub());
694 } 581 }
695 582
696 MUST_USE_RESULT MaybeObject* Store(State state, 583 MUST_USE_RESULT MaybeObject* Store(State state,
697 StrictModeFlag strict_mode, 584 StrictModeFlag strict_mode,
698 Handle<Object> object, 585 Handle<Object> object,
699 Handle<Object> name, 586 Handle<Object> name,
700 Handle<Object> value, 587 Handle<Object> value,
701 ICMissMode force_generic); 588 ICMissMode force_generic);
702 589
703 // Code generators for stub routines. Only called once at startup. 590 // Code generators for stub routines. Only called once at startup.
704 static void GenerateInitialize(MacroAssembler* masm) { 591 static void GenerateInitialize(MacroAssembler* masm) {
705 GenerateMiss(masm, MISS); 592 GenerateMiss(masm, MISS);
706 } 593 }
707 static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic); 594 static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic);
708 static void GenerateSlow(MacroAssembler* masm); 595 static void GenerateSlow(MacroAssembler* masm);
709 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 596 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
710 StrictModeFlag strict_mode); 597 StrictModeFlag strict_mode);
711 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); 598 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
712 static void GenerateNonStrictArguments(MacroAssembler* masm); 599 static void GenerateNonStrictArguments(MacroAssembler* masm);
713 static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm); 600 static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm);
714 static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm); 601 static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm);
715 602
716 virtual Handle<Code> GetElementStubWithoutMapCheck(
717 bool is_js_array,
718 ElementsKind elements_kind,
719 KeyedAccessGrowMode grow_mode);
720
721 protected: 603 protected:
722 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } 604 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
723 605
724 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
725 StrictModeFlag strict_mode,
726 KeyedAccessGrowMode grow_mode);
727
728 // Update the inline cache. 606 // Update the inline cache.
729 virtual void UpdateStoreCaches(LookupResult* lookup, 607 virtual void UpdateStoreCaches(LookupResult* lookup,
730 State state, 608 State state,
731 StrictModeFlag strict_mode, 609 StrictModeFlag strict_mode,
732 Handle<JSObject> receiver, 610 Handle<JSObject> receiver,
733 Handle<String> name, 611 Handle<String> name,
734 Handle<Object> value); 612 Handle<Object> value);
735 613
736 virtual Handle<Code> megamorphic_stub() { 614 virtual Handle<Code> megamorphic_stub() {
737 return isolate()->builtins()->KeyedStoreIC_Generic(); 615 return isolate()->builtins()->KeyedStoreIC_Generic();
738 } 616 }
739 virtual Handle<Code> megamorphic_stub_strict() { 617 virtual Handle<Code> megamorphic_stub_strict() {
740 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 618 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
741 } 619 }
742 620
621 Handle<Code> StoreElementStub(Handle<JSObject> receiver,
622 StubKind stub_kind,
623 StrictModeFlag strict_mode);
624
743 private: 625 private:
744 void set_target(Code* code) { 626 void set_target(Code* code) {
745 // Strict mode must be preserved across IC patching. 627 // Strict mode must be preserved across IC patching.
746 ASSERT(Code::GetStrictMode(code->extra_ic_state()) == 628 ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
747 Code::GetStrictMode(target()->extra_ic_state())); 629 Code::GetStrictMode(target()->extra_ic_state()));
748 IC::set_target(code); 630 IC::set_target(code);
749 } 631 }
750 632
751 // Stub accessors. 633 // Stub accessors.
752 static Handle<Code> initialize_stub() { 634 static Handle<Code> initialize_stub() {
(...skipping 11 matching lines...) Expand all
764 Handle<Code> non_strict_arguments_stub() { 646 Handle<Code> non_strict_arguments_stub() {
765 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); 647 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
766 } 648 }
767 649
768 static void Clear(Address address, Code* target); 650 static void Clear(Address address, Code* target);
769 651
770 StubKind GetStubKind(Handle<JSObject> receiver, 652 StubKind GetStubKind(Handle<JSObject> receiver,
771 Handle<Object> key, 653 Handle<Object> key,
772 Handle<Object> value); 654 Handle<Object> value);
773 655
656 static bool IsTransitionStubKind(StubKind stub_kind) {
657 return stub_kind > STORE_NO_TRANSITION &&
658 stub_kind != STORE_AND_GROW_NO_TRANSITION;
659 }
660
661 static bool IsGrowStubKind(StubKind stub_kind) {
662 return stub_kind >= STORE_AND_GROW_NO_TRANSITION;
663 }
664
665 static StubKind GetNoTransitionStubKind(StubKind stub_kind) {
666 if (!IsTransitionStubKind(stub_kind)) return stub_kind;
667 if (IsGrowStubKind(stub_kind)) return STORE_AND_GROW_NO_TRANSITION;
668 return STORE_NO_TRANSITION;
669 }
670
671 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
672 StubKind stub_kind);
673
774 friend class IC; 674 friend class IC;
775 }; 675 };
776 676
777 677
778 class UnaryOpIC: public IC { 678 class UnaryOpIC: public IC {
779 public: 679 public:
780 // sorted: increasingly more unspecific (ignoring UNINITIALIZED) 680 // sorted: increasingly more unspecific (ignoring UNINITIALIZED)
781 // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead. 681 // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead.
782 enum TypeInfo { 682 enum TypeInfo {
783 UNINITIALIZED, 683 UNINITIALIZED,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 784
885 // Helper for BinaryOpIC and CompareIC. 785 // Helper for BinaryOpIC and CompareIC.
886 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; 786 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
887 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check); 787 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
888 788
889 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss); 789 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss);
890 790
891 } } // namespace v8::internal 791 } } // namespace v8::internal
892 792
893 #endif // V8_IC_H_ 793 #endif // V8_IC_H_
OLDNEW
« no previous file with comments | « no previous file | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698