OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |