OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 20 matching lines...) Expand all Loading... |
32 | 32 |
33 namespace v8 { | 33 namespace v8 { |
34 namespace internal { | 34 namespace internal { |
35 | 35 |
36 | 36 |
37 // IC_UTIL_LIST defines all utility functions called from generated | 37 // IC_UTIL_LIST defines all utility functions called from generated |
38 // inline caching code. The argument for the macro, ICU, is the function name. | 38 // inline caching code. The argument for the macro, ICU, is the function name. |
39 #define IC_UTIL_LIST(ICU) \ | 39 #define IC_UTIL_LIST(ICU) \ |
40 ICU(LoadIC_Miss) \ | 40 ICU(LoadIC_Miss) \ |
41 ICU(KeyedLoadIC_Miss) \ | 41 ICU(KeyedLoadIC_Miss) \ |
| 42 ICU(KeyedLoadIC_MissForceGeneric) \ |
42 ICU(CallIC_Miss) \ | 43 ICU(CallIC_Miss) \ |
43 ICU(KeyedCallIC_Miss) \ | 44 ICU(KeyedCallIC_Miss) \ |
44 ICU(StoreIC_Miss) \ | 45 ICU(StoreIC_Miss) \ |
45 ICU(StoreIC_ArrayLength) \ | 46 ICU(StoreIC_ArrayLength) \ |
46 ICU(SharedStoreIC_ExtendStorage) \ | 47 ICU(SharedStoreIC_ExtendStorage) \ |
47 ICU(KeyedStoreIC_Miss) \ | 48 ICU(KeyedStoreIC_Miss) \ |
| 49 ICU(KeyedStoreIC_MissForceGeneric) \ |
48 /* Utilities for IC stubs. */ \ | 50 /* Utilities for IC stubs. */ \ |
49 ICU(LoadCallbackProperty) \ | 51 ICU(LoadCallbackProperty) \ |
50 ICU(StoreCallbackProperty) \ | 52 ICU(StoreCallbackProperty) \ |
51 ICU(LoadPropertyWithInterceptorOnly) \ | 53 ICU(LoadPropertyWithInterceptorOnly) \ |
52 ICU(LoadPropertyWithInterceptorForLoad) \ | 54 ICU(LoadPropertyWithInterceptorForLoad) \ |
53 ICU(LoadPropertyWithInterceptorForCall) \ | 55 ICU(LoadPropertyWithInterceptorForCall) \ |
54 ICU(KeyedLoadPropertyWithInterceptor) \ | 56 ICU(KeyedLoadPropertyWithInterceptor) \ |
55 ICU(StoreInterceptorProperty) \ | 57 ICU(StoreInterceptorProperty) \ |
56 ICU(TypeRecordingBinaryOp_Patch) \ | 58 ICU(TypeRecordingBinaryOp_Patch) \ |
57 ICU(CompareIC_Miss) | 59 ICU(CompareIC_Miss) |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 #ifdef ENABLE_DEBUGGER_SUPPORT | 136 #ifdef ENABLE_DEBUGGER_SUPPORT |
135 // Computes the address in the original code when the code running is | 137 // Computes the address in the original code when the code running is |
136 // containing break points (calls to DebugBreakXXX builtins). | 138 // containing break points (calls to DebugBreakXXX builtins). |
137 Address OriginalCodeAddress(); | 139 Address OriginalCodeAddress(); |
138 #endif | 140 #endif |
139 | 141 |
140 // Set the call-site target. | 142 // Set the call-site target. |
141 void set_target(Code* code) { SetTargetAtAddress(address(), code); } | 143 void set_target(Code* code) { SetTargetAtAddress(address(), code); } |
142 | 144 |
143 #ifdef DEBUG | 145 #ifdef DEBUG |
144 static void TraceIC(const char* type, | 146 void TraceIC(const char* type, |
145 Handle<Object> name, | 147 Handle<Object> name, |
146 State old_state, | 148 State old_state, |
147 Code* new_target, | 149 Code* new_target, |
148 const char* extra_info = ""); | 150 const char* extra_info = ""); |
149 #endif | 151 #endif |
150 | 152 |
151 Failure* TypeError(const char* type, | 153 Failure* TypeError(const char* type, |
152 Handle<Object> object, | 154 Handle<Object> object, |
153 Handle<Object> key); | 155 Handle<Object> key); |
154 Failure* ReferenceError(const char* type, Handle<String> name); | 156 Failure* ReferenceError(const char* type, Handle<String> name); |
155 | 157 |
156 // Access the target code for the given IC address. | 158 // Access the target code for the given IC address. |
157 static inline Code* GetTargetAtAddress(Address address); | 159 static inline Code* GetTargetAtAddress(Address address); |
158 static inline void SetTargetAtAddress(Address address, Code* target); | 160 static inline void SetTargetAtAddress(Address address, Code* target); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 return isolate()->builtins()->builtin( | 319 return isolate()->builtins()->builtin( |
318 Builtins::kLoadIC_PreMonomorphic); | 320 Builtins::kLoadIC_PreMonomorphic); |
319 } | 321 } |
320 | 322 |
321 static void Clear(Address address, Code* target); | 323 static void Clear(Address address, Code* target); |
322 | 324 |
323 friend class IC; | 325 friend class IC; |
324 }; | 326 }; |
325 | 327 |
326 | 328 |
327 class KeyedLoadIC: public IC { | 329 class KeyedIC: public IC { |
328 public: | 330 public: |
329 explicit KeyedLoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { | 331 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} |
| 332 virtual ~KeyedIC() {} |
| 333 |
| 334 static const int kMaxKeyedPolymorphism = 4; |
| 335 |
| 336 virtual Code::Kind kind() const = 0; |
| 337 |
| 338 virtual String* GetStubNameForCache(IC::State ic_state) = 0; |
| 339 |
| 340 virtual MaybeObject* ConstructSpecializedKeyedIC( |
| 341 Handle<Map> receiver_map, |
| 342 StrictModeFlag strict_mode) = 0; |
| 343 |
| 344 virtual MaybeObject* ConstructMegamorphicKeyedIC( |
| 345 ZoneMapList* receiver_maps, |
| 346 ZoneCodeList* targets, |
| 347 StrictModeFlag strict_mode) = 0; |
| 348 |
| 349 protected: |
| 350 |
| 351 MaybeObject* ComputeKeyedIC(JSObject* receiver, |
| 352 bool is_store, |
| 353 StrictModeFlag strict_mode, |
| 354 Code* default_stub); |
| 355 }; |
| 356 |
| 357 class KeyedLoadIC: public KeyedIC { |
| 358 public: |
| 359 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { |
330 ASSERT(target()->is_keyed_load_stub()); | 360 ASSERT(target()->is_keyed_load_stub()); |
331 } | 361 } |
332 | 362 |
333 MUST_USE_RESULT MaybeObject* Load(State state, | 363 MUST_USE_RESULT MaybeObject* Load(State state, |
334 Handle<Object> object, | 364 Handle<Object> object, |
335 Handle<Object> key); | 365 Handle<Object> key, |
| 366 bool force_generic_stub); |
336 | 367 |
337 // Code generator routines. | 368 // Code generator routines. |
338 static void GenerateMiss(MacroAssembler* masm); | 369 static void GenerateMiss(MacroAssembler* masm, bool force_generic); |
339 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 370 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
340 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 371 static void GenerateInitialize(MacroAssembler* masm) { |
| 372 GenerateMiss(masm, false); |
| 373 } |
341 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 374 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
342 GenerateMiss(masm); | 375 GenerateMiss(masm, false); |
343 } | 376 } |
344 static void GenerateGeneric(MacroAssembler* masm); | 377 static void GenerateGeneric(MacroAssembler* masm); |
345 static void GenerateString(MacroAssembler* masm); | 378 static void GenerateString(MacroAssembler* masm); |
346 | 379 |
347 static void GenerateIndexedInterceptor(MacroAssembler* masm); | 380 static void GenerateIndexedInterceptor(MacroAssembler* masm); |
348 | 381 |
349 // Bit mask to be tested against bit field for the cases when | 382 // Bit mask to be tested against bit field for the cases when |
350 // generic stub should go into slow case. | 383 // generic stub should go into slow case. |
351 // Access check is necessary explicitly since generic stub does not perform | 384 // Access check is necessary explicitly since generic stub does not perform |
352 // map checks. | 385 // map checks. |
353 static const int kSlowCaseBitFieldMask = | 386 static const int kSlowCaseBitFieldMask = |
354 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); | 387 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); |
355 | 388 |
| 389 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } |
| 390 |
| 391 virtual String* GetStubNameForCache(IC::State ic_state); |
| 392 |
| 393 virtual MaybeObject* ConstructSpecializedKeyedIC(Handle<Map> receiver_map, |
| 394 StrictModeFlag strict_mode); |
| 395 |
| 396 virtual MaybeObject* ConstructMegamorphicKeyedIC( |
| 397 ZoneMapList* receiver_maps, |
| 398 ZoneCodeList* targets, |
| 399 StrictModeFlag strict_mode); |
| 400 |
356 private: | 401 private: |
357 // Update the inline cache. | 402 // Update the inline cache. |
358 void UpdateCaches(LookupResult* lookup, | 403 void UpdateCaches(LookupResult* lookup, |
359 State state, | 404 State state, |
360 Handle<Object> object, | 405 Handle<Object> object, |
361 Handle<String> name); | 406 Handle<String> name); |
362 | 407 |
363 // Stub accessors. | 408 // Stub accessors. |
364 static Code* initialize_stub() { | 409 static Code* initialize_stub() { |
365 return Isolate::Current()->builtins()->builtin( | 410 return Isolate::Current()->builtins()->builtin( |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 return isolate()->builtins()->builtin( | 502 return isolate()->builtins()->builtin( |
458 Builtins::kStoreIC_GlobalProxy_Strict); | 503 Builtins::kStoreIC_GlobalProxy_Strict); |
459 } | 504 } |
460 | 505 |
461 static void Clear(Address address, Code* target); | 506 static void Clear(Address address, Code* target); |
462 | 507 |
463 friend class IC; | 508 friend class IC; |
464 }; | 509 }; |
465 | 510 |
466 | 511 |
467 class KeyedStoreIC: public IC { | 512 class KeyedStoreIC: public KeyedIC { |
468 public: | 513 public: |
469 explicit KeyedStoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } | 514 explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) { |
| 515 ASSERT(target()->is_keyed_store_stub()); |
| 516 } |
470 | 517 |
471 MUST_USE_RESULT MaybeObject* Store(State state, | 518 MUST_USE_RESULT MaybeObject* Store(State state, |
472 StrictModeFlag strict_mode, | 519 StrictModeFlag strict_mode, |
473 Handle<Object> object, | 520 Handle<Object> object, |
474 Handle<Object> name, | 521 Handle<Object> name, |
475 Handle<Object> value); | 522 Handle<Object> value, |
| 523 bool force_generic); |
476 | 524 |
477 // Code generators for stub routines. Only called once at startup. | 525 // Code generators for stub routines. Only called once at startup. |
478 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 526 static void GenerateInitialize(MacroAssembler* masm) { |
479 static void GenerateMiss(MacroAssembler* masm); | 527 GenerateMiss(masm, false); |
| 528 } |
| 529 static void GenerateMiss(MacroAssembler* masm, bool force_generic); |
480 static void GenerateRuntimeSetProperty(MacroAssembler* masm, | 530 static void GenerateRuntimeSetProperty(MacroAssembler* masm, |
481 StrictModeFlag strict_mode); | 531 StrictModeFlag strict_mode); |
482 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); | 532 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); |
483 | 533 |
484 private: | 534 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } |
| 535 |
| 536 virtual String* GetStubNameForCache(IC::State ic_state); |
| 537 |
| 538 virtual MaybeObject* ConstructSpecializedKeyedIC(Handle<Map> receiver_map, |
| 539 StrictModeFlag strict_mode); |
| 540 |
| 541 virtual MaybeObject* ConstructMegamorphicKeyedIC( |
| 542 ZoneMapList* receiver_maps, |
| 543 ZoneCodeList* targets, |
| 544 StrictModeFlag strict_mode); |
| 545 |
| 546 private: |
485 // Update the inline cache. | 547 // Update the inline cache. |
486 void UpdateCaches(LookupResult* lookup, | 548 void UpdateCaches(LookupResult* lookup, |
487 State state, | 549 State state, |
488 StrictModeFlag strict_mode, | 550 StrictModeFlag strict_mode, |
489 Handle<JSObject> receiver, | 551 Handle<JSObject> receiver, |
490 Handle<String> name, | 552 Handle<String> name, |
491 Handle<Object> value); | 553 Handle<Object> value); |
492 | 554 |
493 void set_target(Code* code) { | 555 void set_target(Code* code) { |
494 // Strict mode must be preserved across IC patching. | 556 // Strict mode must be preserved across IC patching. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 | 657 |
596 Token::Value op_; | 658 Token::Value op_; |
597 }; | 659 }; |
598 | 660 |
599 // Helper for TRBinaryOpIC and CompareIC. | 661 // Helper for TRBinaryOpIC and CompareIC. |
600 void PatchInlinedSmiCode(Address address); | 662 void PatchInlinedSmiCode(Address address); |
601 | 663 |
602 } } // namespace v8::internal | 664 } } // namespace v8::internal |
603 | 665 |
604 #endif // V8_IC_H_ | 666 #endif // V8_IC_H_ |
OLD | NEW |