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

Side by Side Diff: src/ic.h

Issue 112863002: Merge bleeding_edge 18021:18297 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 return state == UNINITIALIZED || state == PREMONOMORPHIC; 158 return state == UNINITIALIZED || state == PREMONOMORPHIC;
159 } 159 }
160 160
161 // Utility functions to convert maps to types and back. There are two special 161 // Utility functions to convert maps to types and back. There are two special
162 // cases: 162 // cases:
163 // - The heap_number_map is used as a marker which includes heap numbers as 163 // - The heap_number_map is used as a marker which includes heap numbers as
164 // well as smis. 164 // well as smis.
165 // - The oddball map is only used for booleans. 165 // - The oddball map is only used for booleans.
166 static Handle<Map> TypeToMap(Type* type, Isolate* isolate); 166 static Handle<Map> TypeToMap(Type* type, Isolate* isolate);
167 static Type* MapToType(Handle<Map> type); 167 static Type* MapToType(Handle<Map> type);
168 static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate);
168 169
169 protected: 170 protected:
170 // Get the call-site target; used for determining the state. 171 // Get the call-site target; used for determining the state.
171 Handle<Code> target() const { return target_; } 172 Handle<Code> target() const { return target_; }
172 173
173 Address fp() const { return fp_; } 174 Address fp() const { return fp_; }
174 Address pc() const { return *pc_address_; } 175 Address pc() const { return *pc_address_; }
175 Isolate* isolate() const { return isolate_; } 176 Isolate* isolate() const { return isolate_; }
176 177
177 #ifdef ENABLE_DEBUGGER_SUPPORT 178 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 return Handle<Code>::null(); 243 return Handle<Code>::null();
243 } 244 }
244 virtual Handle<Code> megamorphic_stub() { 245 virtual Handle<Code> megamorphic_stub() {
245 UNREACHABLE(); 246 UNREACHABLE();
246 return Handle<Code>::null(); 247 return Handle<Code>::null();
247 } 248 }
248 virtual Handle<Code> generic_stub() const { 249 virtual Handle<Code> generic_stub() const {
249 UNREACHABLE(); 250 UNREACHABLE();
250 return Handle<Code>::null(); 251 return Handle<Code>::null();
251 } 252 }
252 virtual StrictModeFlag strict_mode() const { return kNonStrictMode; } 253
253 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 254 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
254 Handle<String> name); 255 Handle<String> name);
255 void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name); 256 void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
256 257
258 virtual ExtraICState extra_ic_state() { return kNoExtraICState; }
259
257 private: 260 private:
258 Code* raw_target() const { return GetTargetAtAddress(address()); } 261 Code* raw_target() const { return GetTargetAtAddress(address()); }
259 262
260 // Frame pointer for the frame that uses (calls) the IC. 263 // Frame pointer for the frame that uses (calls) the IC.
261 Address fp_; 264 Address fp_;
262 265
263 // All access to the program counter of an IC structure is indirect 266 // All access to the program counter of an IC structure is indirect
264 // to make the code GC safe. This feature is crucial since 267 // to make the code GC safe. This feature is crucial since
265 // GetProperty and SetProperty are called and they in turn might 268 // GetProperty and SetProperty are called and they in turn might
266 // invoke the garbage collector. 269 // invoke the garbage collector.
(...skipping 21 matching lines...) Expand all
288 291
289 IC::UtilityId id() const { return id_; } 292 IC::UtilityId id() const { return id_; }
290 private: 293 private:
291 Address address_; 294 Address address_;
292 IC::UtilityId id_; 295 IC::UtilityId id_;
293 }; 296 };
294 297
295 298
296 class CallICBase: public IC { 299 class CallICBase: public IC {
297 public: 300 public:
298 class Contextual: public BitField<bool, 0, 1> {}; 301 // ExtraICState bits
302 class Contextual: public BitField<ContextualMode, 0, 1> {};
299 class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; 303 class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
304 static ExtraICState ComputeExtraICState(ContextualMode mode,
305 StringStubFeedback feedback) {
306 return Contextual::encode(mode) | StringStubState::encode(feedback);
307 }
300 308
301 // Returns a JSFunction or a Failure. 309 // Returns a JSFunction or a Failure.
302 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, 310 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
303 Handle<String> name); 311 Handle<String> name);
304 312
305 protected: 313 protected:
306 CallICBase(Code::Kind kind, Isolate* isolate) 314 CallICBase(Code::Kind kind, Isolate* isolate)
307 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} 315 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
308 316
309 virtual Code::ExtraICState extra_ic_state() { return Code::kNoExtraICState; }
310
311 // Compute a monomorphic stub if possible, otherwise return a null handle. 317 // Compute a monomorphic stub if possible, otherwise return a null handle.
312 Handle<Code> ComputeMonomorphicStub(LookupResult* lookup, 318 Handle<Code> ComputeMonomorphicStub(LookupResult* lookup,
313 Handle<Object> object, 319 Handle<Object> object,
314 Handle<String> name); 320 Handle<String> name);
315 321
316 // Update the inline cache and the global stub cache based on the lookup 322 // Update the inline cache and the global stub cache based on the lookup
317 // result. 323 // result.
318 void UpdateCaches(LookupResult* lookup, 324 void UpdateCaches(LookupResult* lookup,
319 Handle<Object> object, 325 Handle<Object> object,
320 Handle<String> name); 326 Handle<String> name);
321 327
322 // Returns a JSFunction if the object can be called as a function, and 328 // Returns a JSFunction if the object can be called as a function, and
323 // patches the stack to be ready for the call. Otherwise, it returns the 329 // patches the stack to be ready for the call. Otherwise, it returns the
324 // undefined value. 330 // undefined value.
325 Handle<Object> TryCallAsFunction(Handle<Object> object); 331 Handle<Object> TryCallAsFunction(Handle<Object> object);
326 332
327 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); 333 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
328 334
329 static void Clear(Address address, Code* target); 335 static void Clear(Address address, Code* target);
330 336
331 // Platform-specific code generation functions used by both call and 337 // Platform-specific code generation functions used by both call and
332 // keyed call. 338 // keyed call.
333 static void GenerateMiss(MacroAssembler* masm, 339 static void GenerateMiss(MacroAssembler* masm,
334 int argc, 340 int argc,
335 IC::UtilityId id, 341 IC::UtilityId id,
336 Code::ExtraICState extra_state); 342 ExtraICState extra_state);
337 343
338 static void GenerateNormal(MacroAssembler* masm, int argc); 344 static void GenerateNormal(MacroAssembler* masm, int argc);
339 345
340 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, 346 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
341 int argc, 347 int argc,
342 Code::Kind kind, 348 Code::Kind kind,
343 Code::ExtraICState extra_state); 349 ExtraICState extra_state);
344 350
345 virtual Handle<Code> megamorphic_stub(); 351 virtual Handle<Code> megamorphic_stub();
346 virtual Handle<Code> pre_monomorphic_stub(); 352 virtual Handle<Code> pre_monomorphic_stub();
347 353
348 Code::Kind kind_; 354 Code::Kind kind_;
349 355
350 friend class IC; 356 friend class IC;
351 }; 357 };
352 358
353 359
354 class CallIC: public CallICBase { 360 class CallIC: public CallICBase {
355 public: 361 public:
356 explicit CallIC(Isolate* isolate) 362 explicit CallIC(Isolate* isolate)
357 : CallICBase(Code::CALL_IC, isolate), 363 : CallICBase(Code::CALL_IC, isolate),
358 extra_ic_state_(target()->extra_ic_state()) { 364 extra_ic_state_(target()->extra_ic_state()) {
359 ASSERT(target()->is_call_stub()); 365 ASSERT(target()->is_call_stub());
360 } 366 }
361 367
362 // Code generator routines. 368 // Code generator routines.
363 static void GenerateInitialize(MacroAssembler* masm, 369 static void GenerateInitialize(MacroAssembler* masm,
364 int argc, 370 int argc,
365 Code::ExtraICState extra_state) { 371 ExtraICState extra_state) {
366 GenerateMiss(masm, argc, extra_state); 372 GenerateMiss(masm, argc, extra_state);
367 } 373 }
368 374
369 static void GenerateMiss(MacroAssembler* masm, 375 static void GenerateMiss(MacroAssembler* masm,
370 int argc, 376 int argc,
371 Code::ExtraICState extra_state) { 377 ExtraICState extra_state) {
372 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state); 378 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state);
373 } 379 }
374 380
375 static void GenerateMegamorphic(MacroAssembler* masm, 381 static void GenerateMegamorphic(MacroAssembler* masm,
376 int argc, 382 int argc,
377 Code::ExtraICState extra_ic_state); 383 ExtraICState extra_ic_state);
378 384
379 static void GenerateNormal(MacroAssembler* masm, int argc) { 385 static void GenerateNormal(MacroAssembler* masm, int argc) {
380 CallICBase::GenerateNormal(masm, argc); 386 CallICBase::GenerateNormal(masm, argc);
381 GenerateMiss(masm, argc, Code::kNoExtraICState); 387 GenerateMiss(masm, argc, kNoExtraICState);
382 } 388 }
383 bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object); 389 bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object);
384 390
385 protected: 391 protected:
386 virtual Code::ExtraICState extra_ic_state() { return extra_ic_state_; } 392 virtual ExtraICState extra_ic_state() { return extra_ic_state_; }
387 393
388 private: 394 private:
389 Code::ExtraICState extra_ic_state_; 395 ExtraICState extra_ic_state_;
390 }; 396 };
391 397
392 398
393 class KeyedCallIC: public CallICBase { 399 class KeyedCallIC: public CallICBase {
394 public: 400 public:
395 explicit KeyedCallIC(Isolate* isolate) 401 explicit KeyedCallIC(Isolate* isolate)
396 : CallICBase(Code::KEYED_CALL_IC, isolate) { 402 : CallICBase(Code::KEYED_CALL_IC, isolate) {
397 ASSERT(target()->is_keyed_call_stub()); 403 ASSERT(target()->is_keyed_call_stub());
398 } 404 }
399 405
400 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, 406 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
401 Handle<Object> key); 407 Handle<Object> key);
402 408
403 // Code generator routines. 409 // Code generator routines.
404 static void GenerateInitialize(MacroAssembler* masm, int argc) { 410 static void GenerateInitialize(MacroAssembler* masm, int argc) {
405 GenerateMiss(masm, argc); 411 GenerateMiss(masm, argc);
406 } 412 }
407 413
408 static void GenerateMiss(MacroAssembler* masm, int argc) { 414 static void GenerateMiss(MacroAssembler* masm, int argc) {
409 CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss, 415 CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss,
410 Code::kNoExtraICState); 416 kNoExtraICState);
411 } 417 }
412 418
413 static void GenerateMegamorphic(MacroAssembler* masm, int argc); 419 static void GenerateMegamorphic(MacroAssembler* masm, int argc);
414 static void GenerateNormal(MacroAssembler* masm, int argc); 420 static void GenerateNormal(MacroAssembler* masm, int argc);
415 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); 421 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
416 }; 422 };
417 423
418 424
419 class LoadIC: public IC { 425 class LoadIC: public IC {
420 public: 426 public:
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 } 557 }
552 558
553 static void Clear(Isolate* isolate, Address address, Code* target); 559 static void Clear(Isolate* isolate, Address address, Code* target);
554 560
555 friend class IC; 561 friend class IC;
556 }; 562 };
557 563
558 564
559 class StoreIC: public IC { 565 class StoreIC: public IC {
560 public: 566 public:
567 // ExtraICState bits
568 class StrictModeState: public BitField<StrictModeFlag, 0, 1> {};
569 static ExtraICState ComputeExtraICState(StrictModeFlag flag) {
570 return StrictModeState::encode(flag);
571 }
572
573 static StrictModeFlag GetStrictMode(ExtraICState state) {
574 return StrictModeState::decode(state);
575 }
576
577 // For convenience, a statically declared encoding of strict mode extra
578 // IC state.
579 static const ExtraICState kStrictModeState =
580 1 << StrictModeState::kShift;
581
561 StoreIC(FrameDepth depth, Isolate* isolate) 582 StoreIC(FrameDepth depth, Isolate* isolate)
562 : IC(depth, isolate), 583 : IC(depth, isolate),
563 strict_mode_(Code::GetStrictMode(target()->extra_ic_state())) { 584 strict_mode_(GetStrictMode(target()->extra_ic_state())) {
564 ASSERT(IsStoreStub()); 585 ASSERT(IsStoreStub());
565 } 586 }
566 587
567 virtual StrictModeFlag strict_mode() const { return strict_mode_; } 588 StrictModeFlag strict_mode() const { return strict_mode_; }
568 589
569 // Code generators for stub routines. Only called once at startup. 590 // Code generators for stub routines. Only called once at startup.
570 static void GenerateSlow(MacroAssembler* masm); 591 static void GenerateSlow(MacroAssembler* masm);
571 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 592 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
572 static void GeneratePreMonomorphic(MacroAssembler* masm) { 593 static void GeneratePreMonomorphic(MacroAssembler* masm) {
573 GenerateMiss(masm); 594 GenerateMiss(masm);
574 } 595 }
575 static void GenerateMiss(MacroAssembler* masm); 596 static void GenerateMiss(MacroAssembler* masm);
576 static void GenerateMegamorphic(MacroAssembler* masm, 597 static void GenerateMegamorphic(MacroAssembler* masm,
577 StrictModeFlag strict_mode); 598 ExtraICState extra_ic_state);
578 static void GenerateNormal(MacroAssembler* masm); 599 static void GenerateNormal(MacroAssembler* masm);
579 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 600 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
580 StrictModeFlag strict_mode); 601 StrictModeFlag strict_mode);
581 602
582 MUST_USE_RESULT MaybeObject* Store( 603 MUST_USE_RESULT MaybeObject* Store(
583 Handle<Object> object, 604 Handle<Object> object,
584 Handle<String> name, 605 Handle<String> name,
585 Handle<Object> value, 606 Handle<Object> value,
586 JSReceiver::StoreFromKeyed store_mode = 607 JSReceiver::StoreFromKeyed store_mode =
587 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); 608 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
(...skipping 10 matching lines...) Expand all
598 // Stub accessors. 619 // Stub accessors.
599 virtual Handle<Code> generic_stub() const { 620 virtual Handle<Code> generic_stub() const {
600 if (strict_mode() == kStrictMode) { 621 if (strict_mode() == kStrictMode) {
601 return isolate()->builtins()->StoreIC_Generic_Strict(); 622 return isolate()->builtins()->StoreIC_Generic_Strict();
602 } else { 623 } else {
603 return isolate()->builtins()->StoreIC_Generic(); 624 return isolate()->builtins()->StoreIC_Generic();
604 } 625 }
605 } 626 }
606 627
607 virtual Handle<Code> slow_stub() const { 628 virtual Handle<Code> slow_stub() const {
608 if (strict_mode() == kStrictMode) { 629 return isolate()->builtins()->StoreIC_Slow();
609 return isolate()->builtins()->StoreIC_Slow_Strict();
610 } else {
611 return isolate()->builtins()->StoreIC_Slow();
612 }
613 } 630 }
614 631
615 virtual Handle<Code> pre_monomorphic_stub() { 632 virtual Handle<Code> pre_monomorphic_stub() {
616 return pre_monomorphic_stub(isolate(), strict_mode()); 633 return pre_monomorphic_stub(isolate(), strict_mode());
617 } 634 }
618 635
619 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, 636 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
620 StrictModeFlag strict_mode) { 637 StrictModeFlag strict_mode) {
621 if (strict_mode == kStrictMode) { 638 if (strict_mode == kStrictMode) {
622 return isolate->builtins()->StoreIC_PreMonomorphic_Strict(); 639 return isolate->builtins()->StoreIC_PreMonomorphic_Strict();
623 } else { 640 } else {
624 return isolate->builtins()->StoreIC_PreMonomorphic(); 641 return isolate->builtins()->StoreIC_PreMonomorphic();
625 } 642 }
626 } 643 }
627 644
628 virtual Handle<Code> global_proxy_stub() {
629 if (strict_mode() == kStrictMode) {
630 return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
631 } else {
632 return isolate()->builtins()->StoreIC_GlobalProxy();
633 }
634 }
635
636 // Update the inline cache and the global stub cache based on the 645 // Update the inline cache and the global stub cache based on the
637 // lookup result. 646 // lookup result.
638 void UpdateCaches(LookupResult* lookup, 647 void UpdateCaches(LookupResult* lookup,
639 Handle<JSObject> receiver, 648 Handle<JSObject> receiver,
640 Handle<String> name, 649 Handle<String> name,
641 Handle<Object> value); 650 Handle<Object> value);
642 virtual Handle<Code> CompileHandler(LookupResult* lookup, 651 virtual Handle<Code> CompileHandler(LookupResult* lookup,
643 Handle<Object> object, 652 Handle<Object> object,
644 Handle<String> name, 653 Handle<String> name,
645 Handle<Object> value, 654 Handle<Object> value,
646 InlineCacheHolderFlag cache_holder); 655 InlineCacheHolderFlag cache_holder);
647 656
657 virtual ExtraICState extra_ic_state() {
658 return ComputeExtraICState(strict_mode());
659 }
660
648 private: 661 private:
649 void set_target(Code* code) { 662 void set_target(Code* code) {
650 // Strict mode must be preserved across IC patching. 663 // Strict mode must be preserved across IC patching.
651 ASSERT(Code::GetStrictMode(code->extra_ic_state()) == 664 ASSERT(GetStrictMode(code->extra_ic_state()) ==
652 Code::GetStrictMode(target()->extra_ic_state())); 665 GetStrictMode(target()->extra_ic_state()));
653 IC::set_target(code); 666 IC::set_target(code);
654 } 667 }
655 668
656 static Handle<Code> initialize_stub(Isolate* isolate, 669 static Handle<Code> initialize_stub(Isolate* isolate,
657 StrictModeFlag strict_mode) { 670 StrictModeFlag strict_mode) {
658 if (strict_mode == kStrictMode) { 671 if (strict_mode == kStrictMode) {
659 return isolate->builtins()->StoreIC_Initialize_Strict(); 672 return isolate->builtins()->StoreIC_Initialize_Strict();
660 } else { 673 } else {
661 return isolate->builtins()->StoreIC_Initialize(); 674 return isolate->builtins()->StoreIC_Initialize();
662 } 675 }
(...skipping 14 matching lines...) Expand all
677 690
678 691
679 enum KeyedStoreIncrementLength { 692 enum KeyedStoreIncrementLength {
680 kDontIncrementLength, 693 kDontIncrementLength,
681 kIncrementLength 694 kIncrementLength
682 }; 695 };
683 696
684 697
685 class KeyedStoreIC: public StoreIC { 698 class KeyedStoreIC: public StoreIC {
686 public: 699 public:
700 // ExtraICState bits (building on IC)
701 // ExtraICState bits
702 class ExtraICStateKeyedAccessStoreMode:
703 public BitField<KeyedAccessStoreMode, 1, 4> {}; // NOLINT
704
705 static ExtraICState ComputeExtraICState(StrictModeFlag flag,
706 KeyedAccessStoreMode mode) {
707 return StrictModeState::encode(flag) |
708 ExtraICStateKeyedAccessStoreMode::encode(mode);
709 }
710
711 static KeyedAccessStoreMode GetKeyedAccessStoreMode(
712 ExtraICState extra_state) {
713 return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
714 }
715
687 KeyedStoreIC(FrameDepth depth, Isolate* isolate) 716 KeyedStoreIC(FrameDepth depth, Isolate* isolate)
688 : StoreIC(depth, isolate) { 717 : StoreIC(depth, isolate) {
689 ASSERT(target()->is_keyed_store_stub()); 718 ASSERT(target()->is_keyed_store_stub());
690 } 719 }
691 720
692 MUST_USE_RESULT MaybeObject* Store(Handle<Object> object, 721 MUST_USE_RESULT MaybeObject* Store(Handle<Object> object,
693 Handle<Object> name, 722 Handle<Object> name,
694 Handle<Object> value); 723 Handle<Object> value);
695 724
696 // Code generators for stub routines. Only called once at startup. 725 // Code generators for stub routines. Only called once at startup.
697 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 726 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
698 static void GeneratePreMonomorphic(MacroAssembler* masm) { 727 static void GeneratePreMonomorphic(MacroAssembler* masm) {
699 GenerateMiss(masm); 728 GenerateMiss(masm);
700 } 729 }
701 static void GenerateMiss(MacroAssembler* masm); 730 static void GenerateMiss(MacroAssembler* masm);
702 static void GenerateSlow(MacroAssembler* masm); 731 static void GenerateSlow(MacroAssembler* masm);
703 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 732 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
704 StrictModeFlag strict_mode); 733 StrictModeFlag strict_mode);
705 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); 734 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
706 static void GenerateNonStrictArguments(MacroAssembler* masm); 735 static void GenerateNonStrictArguments(MacroAssembler* masm);
707 736
708 protected: 737 protected:
709 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } 738 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
710 739
711 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } 740 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
712 741
742 virtual ExtraICState extra_ic_state() {
743 return ComputeExtraICState(strict_mode(), STANDARD_STORE);
744 }
745
713 virtual Handle<Code> pre_monomorphic_stub() { 746 virtual Handle<Code> pre_monomorphic_stub() {
714 return pre_monomorphic_stub(isolate(), strict_mode()); 747 return pre_monomorphic_stub(isolate(), strict_mode());
715 } 748 }
716 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, 749 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
717 StrictModeFlag strict_mode) { 750 StrictModeFlag strict_mode) {
718 if (strict_mode == kStrictMode) { 751 if (strict_mode == kStrictMode) {
719 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); 752 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
720 } else { 753 } else {
721 return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); 754 return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
722 } 755 }
723 } 756 }
724 virtual Handle<Code> slow_stub() const { 757 virtual Handle<Code> slow_stub() const {
725 if (strict_mode() == kStrictMode) { 758 return isolate()->builtins()->KeyedStoreIC_Slow();
726 return isolate()->builtins()->KeyedStoreIC_Slow_Strict();
727 } else {
728 return isolate()->builtins()->KeyedStoreIC_Slow();
729 }
730 } 759 }
731 virtual Handle<Code> megamorphic_stub() { 760 virtual Handle<Code> megamorphic_stub() {
732 if (strict_mode() == kStrictMode) { 761 if (strict_mode() == kStrictMode) {
733 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 762 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
734 } else { 763 } else {
735 return isolate()->builtins()->KeyedStoreIC_Generic(); 764 return isolate()->builtins()->KeyedStoreIC_Generic();
736 } 765 }
737 } 766 }
738 767
739 Handle<Code> StoreElementStub(Handle<JSObject> receiver, 768 Handle<Code> StoreElementStub(Handle<JSObject> receiver,
740 KeyedAccessStoreMode store_mode); 769 KeyedAccessStoreMode store_mode);
741 770
742 private: 771 private:
743 void set_target(Code* code) { 772 void set_target(Code* code) {
744 // Strict mode must be preserved across IC patching. 773 // Strict mode must be preserved across IC patching.
745 ASSERT(Code::GetStrictMode(code->extra_ic_state()) == strict_mode()); 774 ASSERT(GetStrictMode(code->extra_ic_state()) == strict_mode());
746 IC::set_target(code); 775 IC::set_target(code);
747 } 776 }
748 777
749 // Stub accessors. 778 // Stub accessors.
750 static Handle<Code> initialize_stub(Isolate* isolate, 779 static Handle<Code> initialize_stub(Isolate* isolate,
751 StrictModeFlag strict_mode) { 780 StrictModeFlag strict_mode) {
752 if (strict_mode == kStrictMode) { 781 if (strict_mode == kStrictMode) {
753 return isolate->builtins()->KeyedStoreIC_Initialize_Strict(); 782 return isolate->builtins()->KeyedStoreIC_Initialize_Strict();
754 } else { 783 } else {
755 return isolate->builtins()->KeyedStoreIC_Initialize(); 784 return isolate->builtins()->KeyedStoreIC_Initialize();
(...skipping 18 matching lines...) Expand all
774 Handle<Object> key, 803 Handle<Object> key,
775 Handle<Object> value); 804 Handle<Object> value);
776 805
777 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, 806 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
778 KeyedAccessStoreMode store_mode); 807 KeyedAccessStoreMode store_mode);
779 808
780 friend class IC; 809 friend class IC;
781 }; 810 };
782 811
783 812
813 // Mode to overwrite BinaryExpression values.
814 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
815
784 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. 816 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
785 class BinaryOpIC: public IC { 817 class BinaryOpIC: public IC {
786 public: 818 public:
787 enum TypeInfo { 819 class State V8_FINAL BASE_EMBEDDED {
788 UNINITIALIZED, 820 public:
789 SMI, 821 explicit State(ExtraICState extra_ic_state);
790 INT32, 822
791 NUMBER, 823 State(Token::Value op, OverwriteMode mode)
792 ODDBALL, 824 : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE),
793 STRING, // Only used for addition operation. 825 result_kind_(NONE) {
794 GENERIC 826 ASSERT_LE(FIRST_TOKEN, op);
827 ASSERT_LE(op, LAST_TOKEN);
828 }
829
830 InlineCacheState GetICState() const {
831 if (Max(left_kind_, right_kind_) == NONE) {
832 return ::v8::internal::UNINITIALIZED;
833 }
834 if (Max(left_kind_, right_kind_) == GENERIC) {
835 return ::v8::internal::MEGAMORPHIC;
836 }
837 if (Min(left_kind_, right_kind_) == GENERIC) {
838 return ::v8::internal::GENERIC;
839 }
840 return ::v8::internal::MONOMORPHIC;
841 }
842
843 ExtraICState GetExtraICState() const;
844
845 static void GenerateAheadOfTime(
846 Isolate*, void (*Generate)(Isolate*, const State&));
847
848 bool CanReuseDoubleBox() const {
849 return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
850 ((mode_ == OVERWRITE_LEFT &&
851 left_kind_ > SMI && left_kind_ <= NUMBER) ||
852 (mode_ == OVERWRITE_RIGHT &&
853 right_kind_ > SMI && right_kind_ <= NUMBER));
854 }
855
856 bool HasSideEffects() const {
857 return Max(left_kind_, right_kind_) == GENERIC;
858 }
859
860 bool UseInlinedSmiCode() const {
861 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
862 }
863
864 static const int FIRST_TOKEN = Token::BIT_OR;
865 static const int LAST_TOKEN = Token::MOD;
866
867 Token::Value op() const { return op_; }
868 OverwriteMode mode() const { return mode_; }
869 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
870
871 Handle<Type> GetLeftType(Isolate* isolate) const {
872 return KindToType(left_kind_, isolate);
873 }
874 Handle<Type> GetRightType(Isolate* isolate) const {
875 return KindToType(right_kind_, isolate);
876 }
877 Handle<Type> GetResultType(Isolate* isolate) const;
878
879 void Print(StringStream* stream) const;
880
881 void Update(Handle<Object> left,
882 Handle<Object> right,
883 Handle<Object> result);
884
885 private:
886 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
887
888 Kind UpdateKind(Handle<Object> object, Kind kind) const;
889
890 static const char* KindToString(Kind kind);
891 static Handle<Type> KindToType(Kind kind, Isolate* isolate);
892 static bool KindMaybeSmi(Kind kind) {
893 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
894 }
895
896 // We truncate the last bit of the token.
897 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
898 class OpField: public BitField<int, 0, 4> {};
899 class OverwriteModeField: public BitField<OverwriteMode, 4, 2> {};
900 class SSE2Field: public BitField<bool, 6, 1> {};
901 class ResultKindField: public BitField<Kind, 7, 3> {};
902 class LeftKindField: public BitField<Kind, 10, 3> {};
903 // When fixed right arg is set, we don't need to store the right kind.
904 // Thus the two fields can overlap.
905 class HasFixedRightArgField: public BitField<bool, 13, 1> {};
906 class FixedRightArgValueField: public BitField<int, 14, 4> {};
907 class RightKindField: public BitField<Kind, 14, 3> {};
908
909 Token::Value op_;
910 OverwriteMode mode_;
911 Kind left_kind_;
912 Kind right_kind_;
913 Kind result_kind_;
914 Maybe<int> fixed_right_arg_;
795 }; 915 };
796 916
797 explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } 917 explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { }
798 918
799 static Builtins::JavaScript TokenToJSBuiltin(Token::Value op); 919 static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
800 920
801 static const char* GetName(TypeInfo type_info);
802
803 MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left, 921 MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left,
804 Handle<Object> right); 922 Handle<Object> right);
805 }; 923 };
806 924
807 925
808 class CompareIC: public IC { 926 class CompareIC: public IC {
809 public: 927 public:
810 // The type/state lattice is defined by the following inequations: 928 // The type/state lattice is defined by the following inequations:
811 // UNINITIALIZED < ... 929 // UNINITIALIZED < ...
812 // ... < GENERIC 930 // ... < GENERIC
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure); 1028 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure);
911 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); 1029 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
912 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); 1030 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss);
913 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); 1031 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
914 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); 1032 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
915 1033
916 1034
917 } } // namespace v8::internal 1035 } } // namespace v8::internal
918 1036
919 #endif // V8_IC_H_ 1037 #endif // V8_IC_H_
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698