v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ic.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_IC_H_
29 #define V8_IC_H_
30 
31 #include "macro-assembler.h"
32 #include "type-info.h"
33 
34 namespace v8 {
35 namespace internal {
36 
37 
38 // IC_UTIL_LIST defines all utility functions called from generated
39 // inline caching code. The argument for the macro, ICU, is the function name.
40 #define IC_UTIL_LIST(ICU) \
41  ICU(LoadIC_Miss) \
42  ICU(KeyedLoadIC_Miss) \
43  ICU(KeyedLoadIC_MissForceGeneric) \
44  ICU(CallIC_Miss) \
45  ICU(KeyedCallIC_Miss) \
46  ICU(StoreIC_Miss) \
47  ICU(StoreIC_ArrayLength) \
48  ICU(SharedStoreIC_ExtendStorage) \
49  ICU(KeyedStoreIC_Miss) \
50  ICU(KeyedStoreIC_MissForceGeneric) \
51  ICU(KeyedStoreIC_Slow) \
52  /* Utilities for IC stubs. */ \
53  ICU(LoadCallbackProperty) \
54  ICU(StoreCallbackProperty) \
55  ICU(LoadPropertyWithInterceptorOnly) \
56  ICU(LoadPropertyWithInterceptorForLoad) \
57  ICU(LoadPropertyWithInterceptorForCall) \
58  ICU(KeyedLoadPropertyWithInterceptor) \
59  ICU(StoreInterceptorProperty) \
60  ICU(UnaryOp_Patch) \
61  ICU(BinaryOp_Patch) \
62  ICU(CompareIC_Miss) \
63  ICU(ToBoolean_Patch)
64 //
65 // IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC,
66 // and KeyedStoreIC.
67 //
68 class IC {
69  public:
70  // The ids for utility called from the generated code.
71  enum UtilityId {
72  #define CONST_NAME(name) k##name,
74  #undef CONST_NAME
76  };
77 
78  // Looks up the address of the named utility.
80 
81  // Alias the inline cache state type to make the IC code more readable.
83 
84  // The IC code is either invoked with no extra frames on the stack
85  // or with a single extra frame for supporting calls.
86  enum FrameDepth {
89  };
90 
91  // Construct the IC structure with the given number of extra
92  // JavaScript frames on the stack.
93  IC(FrameDepth depth, Isolate* isolate);
94  virtual ~IC() {}
95 
96  // Get the call-site target; used for determining the state.
97  Code* target() const { return GetTargetAtAddress(address()); }
98  inline Address address() const;
99 
100  virtual bool IsGeneric() const { return false; }
101 
102  // Compute the current IC state based on the target stub, receiver and name.
103  static State StateFrom(Code* target, Object* receiver, Object* name);
104 
105  // Clear the inline cache to initial state.
106  static void Clear(Address address);
107 
108  // Computes the reloc info for this IC. This is a fairly expensive
109  // operation as it has to search through the heap to find the code
110  // object that contains this IC site.
111  RelocInfo::Mode ComputeMode();
112 
113  // Returns if this IC is for contextual (no explicit receiver)
114  // access to properties.
115  bool IsContextual(Handle<Object> receiver) {
116  if (receiver->IsGlobalObject()) {
117  return SlowIsContextual();
118  } else {
120  return false;
121  }
122  }
123 
125  return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
126  }
127 
128  // Determines which map must be used for keeping the code stub.
129  // These methods should not be called with undefined or null.
130  static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object,
131  JSObject* holder);
133  JSObject* holder);
134  static inline JSObject* GetCodeCacheHolder(Object* object,
135  InlineCacheHolderFlag holder);
136 
137  protected:
138  Address fp() const { return fp_; }
139  Address pc() const { return *pc_address_; }
140  Isolate* isolate() const { return isolate_; }
141 
142 #ifdef ENABLE_DEBUGGER_SUPPORT
143  // Computes the address in the original code when the code running is
144  // containing break points (calls to DebugBreakXXX builtins).
145  Address OriginalCodeAddress() const;
146 #endif
147 
148  // Set the call-site target.
150 
151 #ifdef DEBUG
152  char TransitionMarkFromState(IC::State state);
153 
154  void TraceIC(const char* type,
155  Handle<Object> name,
156  State old_state,
157  Code* new_target);
158 #endif
159 
160  Failure* TypeError(const char* type,
161  Handle<Object> object,
162  Handle<Object> key);
163  Failure* ReferenceError(const char* type, Handle<String> name);
164 
165  // Access the target code for the given IC address.
166  static inline Code* GetTargetAtAddress(Address address);
167  static inline void SetTargetAtAddress(Address address, Code* target);
168  static void PostPatching(Address address, Code* target, Code* old_target);
169 
170  private:
171  // Frame pointer for the frame that uses (calls) the IC.
172  Address fp_;
173 
174  // All access to the program counter of an IC structure is indirect
175  // to make the code GC safe. This feature is crucial since
176  // GetProperty and SetProperty are called and they in turn might
177  // invoke the garbage collector.
178  Address* pc_address_;
179 
180  Isolate* isolate_;
181 
182  DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
183 };
184 
185 
186 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you
187 // cannot make forward declarations to an enum.
188 class IC_Utility {
189  public:
191  : address_(IC::AddressFromUtilityId(id)), id_(id) {}
192 
193  Address address() const { return address_; }
194 
195  IC::UtilityId id() const { return id_; }
196  private:
197  Address address_;
198  IC::UtilityId id_;
199 };
200 
201 
202 class CallICBase: public IC {
203  public:
204  class Contextual: public BitField<bool, 0, 1> {};
205  class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
206 
207  // Returns a JSFunction or a Failure.
208  MUST_USE_RESULT MaybeObject* LoadFunction(State state,
209  Code::ExtraICState extra_ic_state,
210  Handle<Object> object,
211  Handle<String> name);
212 
213  protected:
215  : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
216 
217  bool TryUpdateExtraICState(LookupResult* lookup,
218  Handle<Object> object,
219  Code::ExtraICState* extra_ic_state);
220 
221  // Compute a monomorphic stub if possible, otherwise return a null handle.
222  Handle<Code> ComputeMonomorphicStub(LookupResult* lookup,
223  State state,
224  Code::ExtraICState extra_state,
225  Handle<Object> object,
226  Handle<String> name);
227 
228  // Update the inline cache and the global stub cache based on the lookup
229  // result.
230  void UpdateCaches(LookupResult* lookup,
231  State state,
232  Code::ExtraICState extra_ic_state,
233  Handle<Object> object,
234  Handle<String> name);
235 
236  // Returns a JSFunction if the object can be called as a function, and
237  // patches the stack to be ready for the call. Otherwise, it returns the
238  // undefined value.
240 
242 
243  static void Clear(Address address, Code* target);
244 
245  // Platform-specific code generation functions used by both call and
246  // keyed call.
247  static void GenerateMiss(MacroAssembler* masm,
248  int argc,
249  IC::UtilityId id,
250  Code::ExtraICState extra_state);
251 
252  static void GenerateNormal(MacroAssembler* masm, int argc);
253 
255  int argc,
256  Code::Kind kind,
257  Code::ExtraICState extra_state);
258 
260 
261  friend class IC;
262 };
263 
264 
265 class CallIC: public CallICBase {
266  public:
267  explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) {
268  ASSERT(target()->is_call_stub());
269  }
270 
271  // Code generator routines.
273  int argc,
274  Code::ExtraICState extra_state) {
275  GenerateMiss(masm, argc, extra_state);
276  }
277 
278  static void GenerateMiss(MacroAssembler* masm,
279  int argc,
280  Code::ExtraICState extra_state) {
281  CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state);
282  }
283 
284  static void GenerateMegamorphic(MacroAssembler* masm,
285  int argc,
286  Code::ExtraICState extra_ic_state);
287 
288  static void GenerateNormal(MacroAssembler* masm, int argc) {
289  CallICBase::GenerateNormal(masm, argc);
290  GenerateMiss(masm, argc, Code::kNoExtraICState);
291  }
292 };
293 
294 
295 class KeyedCallIC: public CallICBase {
296  public:
298  : CallICBase(Code::KEYED_CALL_IC, isolate) {
299  ASSERT(target()->is_keyed_call_stub());
300  }
301 
302  MUST_USE_RESULT MaybeObject* LoadFunction(State state,
303  Handle<Object> object,
304  Handle<Object> key);
305 
306  // Code generator routines.
307  static void GenerateInitialize(MacroAssembler* masm, int argc) {
308  GenerateMiss(masm, argc);
309  }
310 
311  static void GenerateMiss(MacroAssembler* masm, int argc) {
312  CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss,
314  }
315 
316  static void GenerateMegamorphic(MacroAssembler* masm, int argc);
317  static void GenerateNormal(MacroAssembler* masm, int argc);
318  static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
319 };
320 
321 
322 class LoadIC: public IC {
323  public:
324  explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
325  ASSERT(target()->is_load_stub());
326  }
327 
328  MUST_USE_RESULT MaybeObject* Load(State state,
329  Handle<Object> object,
330  Handle<String> name);
331 
332  // Code generator routines.
333  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
335  GenerateMiss(masm);
336  }
337  static void GenerateMiss(MacroAssembler* masm);
338  static void GenerateMegamorphic(MacroAssembler* masm);
339  static void GenerateNormal(MacroAssembler* masm);
340 
341  // Specialized code generator routines.
342  static void GenerateArrayLength(MacroAssembler* masm);
343  static void GenerateStringLength(MacroAssembler* masm,
344  bool support_wrappers);
345  static void GenerateFunctionPrototype(MacroAssembler* masm);
346 
347  private:
348  // Update the inline cache and the global stub cache based on the
349  // lookup result.
350  void UpdateCaches(LookupResult* lookup,
351  State state,
352  Handle<Object> object,
353  Handle<String> name);
354 
355  // Stub accessors.
356  Handle<Code> megamorphic_stub() {
357  return isolate()->builtins()->LoadIC_Megamorphic();
358  }
359  static Code* initialize_stub() {
360  return Isolate::Current()->builtins()->builtin(
361  Builtins::kLoadIC_Initialize);
362  }
363  Handle<Code> pre_monomorphic_stub() {
364  return isolate()->builtins()->LoadIC_PreMonomorphic();
365  }
366 
367  static void Clear(Address address, Code* target);
368 
369  friend class IC;
370 };
371 
372 
373 class KeyedIC: public IC {
374  public:
375  enum StubKind {
391  };
392 
404 
405  explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
406  virtual ~KeyedIC() {}
407 
409  StubKind stub_kind) {
410  return (stub_kind >= STORE_AND_GROW_NO_TRANSITION)
413  }
414 
415  static inline StubKind GetGrowStubKind(StubKind stub_kind) {
416  ASSERT(stub_kind != LOAD);
417  if (stub_kind < STORE_AND_GROW_NO_TRANSITION) {
418  stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) +
419  kGrowICDelta);
420  }
421  return stub_kind;
422  }
423 
425  bool is_js_array,
426  ElementsKind elements_kind,
427  KeyedAccessGrowMode grow_mode) = 0;
428 
429  protected:
431  return Handle<Code>::null();
432  }
433 
434  virtual Code::Kind kind() const = 0;
435 
437  StubKind stub_kind,
438  StrictModeFlag strict_mode,
439  Handle<Code> default_stub);
440 
442  MapHandleList* receiver_maps,
443  StrictModeFlag strict_mode,
444  KeyedAccessGrowMode grow_mode) = 0;
445 
447  Handle<Map> receiver_map,
448  StrictModeFlag strict_mode,
449  KeyedAccessGrowMode grow_mode);
450 
451  private:
452  void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
453 
454  Handle<Code> ComputeMonomorphicStub(Handle<Map> receiver_map,
455  StubKind stub_kind,
456  StrictModeFlag strict_mode,
457  Handle<Code> default_stub);
458 
459  Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
460  StubKind stub_kind);
461 
462  static bool IsTransitionStubKind(StubKind stub_kind) {
463  return stub_kind > STORE_NO_TRANSITION &&
464  stub_kind != STORE_AND_GROW_NO_TRANSITION;
465  }
466 
467  static bool IsGrowStubKind(StubKind stub_kind) {
468  return stub_kind >= STORE_AND_GROW_NO_TRANSITION;
469  }
470 
471  static StubKind GetNoTransitionStubKind(StubKind stub_kind) {
472  if (!IsTransitionStubKind(stub_kind)) return stub_kind;
473  if (IsGrowStubKind(stub_kind)) return STORE_AND_GROW_NO_TRANSITION;
474  return STORE_NO_TRANSITION;
475  }
476 };
477 
478 
479 class KeyedLoadIC: public KeyedIC {
480  public:
481  explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) {
482  ASSERT(target()->is_keyed_load_stub());
483  }
484 
485  MUST_USE_RESULT MaybeObject* Load(State state,
486  Handle<Object> object,
487  Handle<Object> key,
488  bool force_generic_stub);
489 
490  // Code generator routines.
491  static void GenerateMiss(MacroAssembler* masm, bool force_generic);
492  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
493  static void GenerateInitialize(MacroAssembler* masm) {
494  GenerateMiss(masm, false);
495  }
497  GenerateMiss(masm, false);
498  }
499  static void GenerateGeneric(MacroAssembler* masm);
500  static void GenerateString(MacroAssembler* masm);
501  static void GenerateIndexedInterceptor(MacroAssembler* masm);
502  static void GenerateNonStrictArguments(MacroAssembler* masm);
503 
504  // Bit mask to be tested against bit field for the cases when
505  // generic stub should go into slow case.
506  // Access check is necessary explicitly since generic stub does not perform
507  // map checks.
508  static const int kSlowCaseBitFieldMask =
510 
512  bool is_js_array,
513  ElementsKind elements_kind,
514  KeyedAccessGrowMode grow_mode);
515 
516  virtual bool IsGeneric() const {
517  return target() == *generic_stub();
518  }
519 
520  protected:
521  virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
522 
523  virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
524  StrictModeFlag strict_mode,
525  KeyedAccessGrowMode grow_mode);
526 
528  return isolate()->builtins()->KeyedLoadIC_String();
529  }
530 
531  private:
532  // Update the inline cache.
533  void UpdateCaches(LookupResult* lookup,
534  State state,
535  Handle<Object> object,
536  Handle<String> name);
537 
538  // Stub accessors.
539  static Code* initialize_stub() {
540  return Isolate::Current()->builtins()->builtin(
541  Builtins::kKeyedLoadIC_Initialize);
542  }
543  Handle<Code> megamorphic_stub() {
544  return isolate()->builtins()->KeyedLoadIC_Generic();
545  }
546  Handle<Code> generic_stub() const {
547  return isolate()->builtins()->KeyedLoadIC_Generic();
548  }
549  Handle<Code> pre_monomorphic_stub() {
550  return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
551  }
552  Handle<Code> indexed_interceptor_stub() {
553  return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
554  }
555  Handle<Code> non_strict_arguments_stub() {
556  return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
557  }
558 
559  static void Clear(Address address, Code* target);
560 
561  friend class IC;
562 };
563 
564 
565 class StoreIC: public IC {
566  public:
567  explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
568  ASSERT(target()->is_store_stub());
569  }
570 
571  MUST_USE_RESULT MaybeObject* Store(State state,
572  StrictModeFlag strict_mode,
573  Handle<Object> object,
574  Handle<String> name,
575  Handle<Object> value);
576 
577  // Code generators for stub routines. Only called once at startup.
578  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
579  static void GenerateMiss(MacroAssembler* masm);
580  static void GenerateMegamorphic(MacroAssembler* masm,
581  StrictModeFlag strict_mode);
582  static void GenerateArrayLength(MacroAssembler* masm);
583  static void GenerateNormal(MacroAssembler* masm);
584  static void GenerateGlobalProxy(MacroAssembler* masm,
585  StrictModeFlag strict_mode);
586 
587  private:
588  // Update the inline cache and the global stub cache based on the
589  // lookup result.
590  void UpdateCaches(LookupResult* lookup,
591  State state,
592  StrictModeFlag strict_mode,
593  Handle<JSObject> receiver,
594  Handle<String> name,
595  Handle<Object> value);
596 
597  void set_target(Code* code) {
598  // Strict mode must be preserved across IC patching.
601  IC::set_target(code);
602  }
603 
604  // Stub accessors.
605  Code* megamorphic_stub() {
606  return isolate()->builtins()->builtin(
607  Builtins::kStoreIC_Megamorphic);
608  }
609  Code* megamorphic_stub_strict() {
610  return isolate()->builtins()->builtin(
611  Builtins::kStoreIC_Megamorphic_Strict);
612  }
613  static Code* initialize_stub() {
614  return Isolate::Current()->builtins()->builtin(
615  Builtins::kStoreIC_Initialize);
616  }
617  static Code* initialize_stub_strict() {
618  return Isolate::Current()->builtins()->builtin(
619  Builtins::kStoreIC_Initialize_Strict);
620  }
621  Handle<Code> global_proxy_stub() {
622  return isolate()->builtins()->StoreIC_GlobalProxy();
623  }
624  Handle<Code> global_proxy_stub_strict() {
625  return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
626  }
627 
628  static void Clear(Address address, Code* target);
629 
630  friend class IC;
631 };
632 
633 
637 };
638 
639 
643 };
644 
645 
646 class KeyedStoreIC: public KeyedIC {
647  public:
648  explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) {
649  ASSERT(target()->is_keyed_store_stub());
650  }
651 
652  MUST_USE_RESULT MaybeObject* Store(State state,
653  StrictModeFlag strict_mode,
654  Handle<Object> object,
655  Handle<Object> name,
656  Handle<Object> value,
657  bool force_generic);
658 
659  // Code generators for stub routines. Only called once at startup.
660  static void GenerateInitialize(MacroAssembler* masm) {
661  GenerateMiss(masm, false);
662  }
663  static void GenerateMiss(MacroAssembler* masm, bool force_generic);
664  static void GenerateSlow(MacroAssembler* masm);
665  static void GenerateRuntimeSetProperty(MacroAssembler* masm,
666  StrictModeFlag strict_mode);
667  static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
668  static void GenerateNonStrictArguments(MacroAssembler* masm);
671 
673  bool is_js_array,
674  ElementsKind elements_kind,
675  KeyedAccessGrowMode grow_mode);
676 
677  virtual bool IsGeneric() const {
678  return target() == *generic_stub() ||
679  target() == *generic_stub_strict();
680  }
681 
682  protected:
683  virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
684 
685  virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
686  StrictModeFlag strict_mode,
687  KeyedAccessGrowMode grow_mode);
688 
689  private:
690  // Update the inline cache.
691  void UpdateCaches(LookupResult* lookup,
692  State state,
693  StrictModeFlag strict_mode,
694  Handle<JSObject> receiver,
695  Handle<String> name,
696  Handle<Object> value);
697 
698  void set_target(Code* code) {
699  // Strict mode must be preserved across IC patching.
702  IC::set_target(code);
703  }
704 
705  // Stub accessors.
706  static Code* initialize_stub() {
707  return Isolate::Current()->builtins()->builtin(
708  Builtins::kKeyedStoreIC_Initialize);
709  }
710  static Code* initialize_stub_strict() {
711  return Isolate::Current()->builtins()->builtin(
712  Builtins::kKeyedStoreIC_Initialize_Strict);
713  }
714  Handle<Code> megamorphic_stub() {
715  return isolate()->builtins()->KeyedStoreIC_Generic();
716  }
717  Handle<Code> megamorphic_stub_strict() {
718  return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
719  }
720  Handle<Code> generic_stub() const {
721  return isolate()->builtins()->KeyedStoreIC_Generic();
722  }
723  Handle<Code> generic_stub_strict() const {
724  return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
725  }
726  Handle<Code> non_strict_arguments_stub() {
727  return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
728  }
729 
730  static void Clear(Address address, Code* target);
731 
732  StubKind GetStubKind(Handle<JSObject> receiver,
733  Handle<Object> key,
734  Handle<Object> value);
735 
736  friend class IC;
737 };
738 
739 
740 class UnaryOpIC: public IC {
741  public:
742  // sorted: increasingly more unspecific (ignoring UNINITIALIZED)
743  // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead.
744  enum TypeInfo {
749  };
750 
751  explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
752 
753  void patch(Code* code);
754 
755  static const char* GetName(TypeInfo type_info);
756 
757  static State ToState(TypeInfo type_info);
758 
759  static TypeInfo GetTypeInfo(Handle<Object> operand);
760 
761  static TypeInfo ComputeNewType(TypeInfo type, TypeInfo previous);
762 };
763 
764 
765 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
766 class BinaryOpIC: public IC {
767  public:
768  enum TypeInfo {
774  BOTH_STRING, // Only used for addition operation.
775  STRING, // Only used for addition operation. At least one string operand.
777  };
778 
779  explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
780 
781  void patch(Code* code);
782 
783  static const char* GetName(TypeInfo type_info);
784 
785  static State ToState(TypeInfo type_info);
786 
788 
789  static TypeInfo JoinTypes(TypeInfo x, TypeInfo y);
790 };
791 
792 
793 class CompareIC: public IC {
794  public:
795  enum State {
804  };
805 
807  : IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
808 
809  // Update the inline cache for the given operands.
811 
812  // Factory method for getting an uninitialized compare stub.
814 
815  // Helper function for computing the condition for a compare operation.
817 
818  // Helper function for determining the state of a compare IC.
819  static State ComputeState(Code* target);
820 
821  // Helper function for determining the operation a compare IC is for.
823 
824  static const char* GetStateName(State state);
825 
826  private:
827  State TargetState(State state, bool has_inlined_smi_code,
829 
830  bool strict() const { return op_ == Token::EQ_STRICT; }
831  Condition GetCondition() const { return ComputeCondition(op_); }
832  State GetState() { return ComputeState(target()); }
833 
834  static Code* GetRawUninitialized(Token::Value op);
835 
836  static void Clear(Address address, Code* target);
837 
838  Token::Value op_;
839 
840  friend class IC;
841 };
842 
843 
844 class ToBooleanIC: public IC {
845  public:
846  explicit ToBooleanIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
847 
848  void patch(Code* code);
849 };
850 
851 
852 // Helper for BinaryOpIC and CompareIC.
855 
856 } } // namespace v8::internal
857 
858 #endif // V8_IC_H_
byte * Address
Definition: globals.h:157
void patch(Code *code)
Definition: ic.cc:2685
virtual Handle< Code > string_stub()
Definition: ic.h:527
static TypeInfo GetTypeInfo(Handle< Object > operand)
Definition: ic.cc:2266
static void GenerateTransitionElementsDoubleToObject(MacroAssembler *masm)
CallIC(Isolate *isolate)
Definition: ic.h:267
static void GenerateRuntimeGetProperty(MacroAssembler *masm)
Code * builtin(Name name)
Definition: builtins.h:320
void UpdateCaches(LookupResult *lookup, State state, Code::ExtraICState extra_ic_state, Handle< Object > object, Handle< String > name)
Definition: ic.cc:694
virtual Code::Kind kind() const
Definition: ic.h:683
virtual Code::Kind kind() const =0
bool SlowIsContextual()
Definition: ic.h:124
Code * target() const
Definition: ic.h:97
static void GenerateNormal(MacroAssembler *masm, int argc)
virtual bool IsGeneric() const
Definition: ic.h:100
static void GenerateGeneric(MacroAssembler *masm, StrictModeFlag strict_mode)
IC_Utility(IC::UtilityId id)
Definition: ic.h:190
static const char * GetName(TypeInfo type_info)
Definition: ic.cc:2241
virtual Handle< Code > GetElementStubWithoutMapCheck(bool is_js_array, ElementsKind elements_kind, KeyedAccessGrowMode grow_mode)
Definition: ic.cc:1755
static void GenerateMiss(MacroAssembler *masm, int argc, IC::UtilityId id, Code::ExtraICState extra_state)
MUST_USE_RESULT MaybeObject * LoadFunction(State state, Handle< Object > object, Handle< Object > key)
Definition: ic.cc:766
void patch(Code *code)
Definition: ic.cc:2236
virtual ~IC()
Definition: ic.h:94
MUST_USE_RESULT MaybeObject * Load(State state, Handle< Object > object, Handle< String > name)
Definition: ic.cc:814
CompareIC(Isolate *isolate, Token::Value op)
Definition: ic.h:806
static void GenerateGlobalProxy(MacroAssembler *masm, StrictModeFlag strict_mode)
static const int kGrowICDelta
Definition: ic.h:393
static void GenerateMegamorphic(MacroAssembler *masm, StrictModeFlag strict_mode)
static void GenerateStringLength(MacroAssembler *masm, bool support_wrappers)
Builtins * builtins()
Definition: isolate.h:924
KeyedStoreCheckMap
Definition: ic.h:634
static const int kIsAccessCheckNeeded
Definition: objects.h:5173
Address address() const
Definition: ic-inl.h:41
static void GenerateMegamorphic(MacroAssembler *masm)
Failure * TypeError(const char *type, Handle< Object > object, Handle< Object > key)
Definition: ic.cc:280
#define ASSERT(condition)
Definition: checks.h:270
virtual ~KeyedIC()
Definition: ic.h:406
static State StateFrom(Code *target, Object *receiver, Object *name)
Definition: ic.cc:227
static StubKind GetGrowStubKind(StubKind stub_kind)
Definition: ic.h:415
Address address() const
Definition: ic.h:193
static TypeInfo GetTypeInfo(Handle< Object > left, Handle< Object > right)
Definition: ic.cc:2355
Code::Kind kind_
Definition: ic.h:259
static const char * GetName(TypeInfo type_info)
Definition: ic.cc:2306
Isolate * isolate() const
Definition: ic.h:140
static const ExtraICState kNoExtraICState
Definition: objects.h:4236
KeyedCallIC(Isolate *isolate)
Definition: ic.h:297
MUST_USE_RESULT MaybeObject * Store(State state, StrictModeFlag strict_mode, Handle< Object > object, Handle< String > name, Handle< Object > value)
Definition: ic.cc:1341
static State ToState(TypeInfo type_info)
Definition: ic.cc:2321
void ReceiverToObjectIfRequired(Handle< Object > callee, Handle< Object > object)
Definition: ic.cc:485
void PatchInlinedSmiCode(Address address, InlinedSmiCheck check)
static void GenerateArrayLength(MacroAssembler *masm)
static void GenerateInitialize(MacroAssembler *masm, int argc, Code::ExtraICState extra_state)
Definition: ic.h:272
static const int kHasIndexedInterceptor
Definition: objects.h:5170
void UpdateCaches(Handle< Object > x, Handle< Object > y)
KeyedIC(Isolate *isolate)
Definition: ic.h:405
static Condition ComputeCondition(Token::Value op)
static void PostPatching(Address address, Code *target, Code *old_target)
Definition: ic.cc:309
Address pc() const
Definition: ic.h:139
static void GenerateInitialize(MacroAssembler *masm)
Definition: ic.h:493
static KeyedAccessGrowMode GetGrowModeFromStubKind(StubKind stub_kind)
Definition: ic.h:408
#define MUST_USE_RESULT
Definition: globals.h:346
Address fp() const
Definition: ic.h:138
IC(FrameDepth depth, Isolate *isolate)
Definition: ic.cc:112
static StrictModeFlag GetStrictMode(ExtraICState extra_ic_state)
Definition: objects.h:4414
static void GeneratePreMonomorphic(MacroAssembler *masm)
Definition: ic.h:334
static void GenerateGeneric(MacroAssembler *masm)
static Code * GetTargetAtAddress(Address address)
Definition: ic-inl.h:69
static void GenerateInitialize(MacroAssembler *masm)
Definition: ic.h:333
KeyedLoadIC(Isolate *isolate)
Definition: ic.h:481
static void GenerateMiss(MacroAssembler *masm)
static void GenerateNormal(MacroAssembler *masm, int argc)
Definition: ic.h:288
UnaryOpIC(Isolate *isolate)
Definition: ic.h:751
ToBooleanIC(Isolate *isolate)
Definition: ic.h:846
MUST_USE_RESULT MaybeObject * LoadFunction(State state, Code::ExtraICState extra_ic_state, Handle< Object > object, Handle< String > name)
Definition: ic.cc:511
StoreIC(Isolate *isolate)
Definition: ic.h:567
static void Clear(Address address, Code *target)
Definition: ic.cc:371
static State ToState(TypeInfo type_info)
Definition: ic.cc:2252
virtual bool IsGeneric() const
Definition: ic.h:516
IC::UtilityId id() const
Definition: ic.h:195
Definition: v8.h:105
virtual Handle< Code > GetElementStubWithoutMapCheck(bool is_js_array, ElementsKind elements_kind, KeyedAccessGrowMode grow_mode)
Definition: ic.cc:1049
STATIC_ASSERT(kGrowICDelta==STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT-STORE_TRANSITION_SMI_TO_OBJECT)
static void GenerateMegamorphic(MacroAssembler *masm, int argc)
virtual Handle< Code > ComputePolymorphicStub(MapHandleList *receiver_maps, StrictModeFlag strict_mode, KeyedAccessGrowMode grow_mode)
Definition: ic.cc:1058
static TypeInfo ComputeNewType(TypeInfo type, TypeInfo previous)
Definition: ic.cc:2279
Handle< Object > TryCallAsFunction(Handle< Object > object)
Definition: ic.cc:468
static void GenerateSlow(MacroAssembler *masm)
static void GenerateMiss(MacroAssembler *masm, int argc, Code::ExtraICState extra_state)
Definition: ic.h:278
InlineCacheState State
Definition: ic.h:82
static void GenerateRuntimeSetProperty(MacroAssembler *masm, StrictModeFlag strict_mode)
MUST_USE_RESULT MaybeObject * Load(State state, Handle< Object > object, Handle< Object > key, bool force_generic_stub)
Definition: ic.cc:1099
static const int kSlowCaseBitFieldMask
Definition: ic.h:508
KeyedStoreIncrementLength
Definition: ic.h:640
static void GenerateNormal(MacroAssembler *masm, int argc)
#define IC_UTIL_LIST(ICU)
Definition: ic.h:40
InlinedSmiCheck
Definition: ic.h:853
ExtraICState extra_ic_state()
Definition: objects-inl.h:3181
static void GenerateMonomorphicCacheProbe(MacroAssembler *masm, int argc, Code::Kind kind, Code::ExtraICState extra_state)
static void GenerateString(MacroAssembler *masm)
static Token::Value ComputeOperation(Code *target)
Definition: ic.cc:2579
static Handle< T > null()
Definition: handles.h:86
virtual Handle< Code > ComputePolymorphicStub(MapHandleList *receiver_maps, StrictModeFlag strict_mode, KeyedAccessGrowMode grow_mode)
Definition: ic.cc:1763
CallICBase(Code::Kind kind, Isolate *isolate)
Definition: ic.h:214
LoadIC(Isolate *isolate)
Definition: ic.h:324
static JSObject * GetCodeCacheHolder(Object *object, InlineCacheHolderFlag holder)
Definition: ic-inl.h:131
static void SetTargetAtAddress(Address address, Code *target)
Definition: ic-inl.h:80
virtual Handle< Code > ComputePolymorphicStub(MapHandleList *receiver_maps, StrictModeFlag strict_mode, KeyedAccessGrowMode grow_mode)=0
static void GenerateNonStrictArguments(MacroAssembler *masm)
static State ComputeState(Code *target)
Definition: ic.cc:2571
virtual Handle< Code > string_stub()
Definition: ic.h:430
static void GenerateMegamorphic(MacroAssembler *masm, int argc, Code::ExtraICState extra_ic_state)
Handle< Code > ComputeMonomorphicStub(LookupResult *lookup, State state, Code::ExtraICState extra_state, Handle< Object > object, Handle< String > name)
Definition: ic.cc:640
Handle< Code > ComputeStub(Handle< JSObject > receiver, StubKind stub_kind, StrictModeFlag strict_mode, Handle< Code > default_stub)
Definition: ic.cc:1593
static void GenerateNormal(MacroAssembler *masm)
static void GenerateFunctionPrototype(MacroAssembler *masm)
static void GenerateIndexedInterceptor(MacroAssembler *masm)
bool TryUpdateExtraICState(LookupResult *lookup, Handle< Object > object, Code::ExtraICState *extra_ic_state)
Definition: ic.cc:596
static void GenerateInitialize(MacroAssembler *masm)
Definition: ic.h:578
void set_target(Code *code)
Definition: ic.h:149
virtual Handle< Code > GetElementStubWithoutMapCheck(bool is_js_array, ElementsKind elements_kind, KeyedAccessGrowMode grow_mode)=0
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static TypeInfo JoinTypes(TypeInfo x, TypeInfo y)
Definition: ic.cc:2340
KeyedStoreIC(Isolate *isolate)
Definition: ic.h:648
static void GenerateNonStrictArguments(MacroAssembler *masm)
BinaryOpIC(Isolate *isolate)
Definition: ic.h:779
static void GenerateMiss(MacroAssembler *masm, bool force_generic)
virtual Code::Kind kind() const
Definition: ic.h:521
static void GenerateMiss(MacroAssembler *masm)
static void GenerateTransitionElementsSmiToDouble(MacroAssembler *masm)
static void GenerateNonStrictArguments(MacroAssembler *masm, int argc)
static void GenerateArrayLength(MacroAssembler *masm)
static const char * GetStateName(State state)
Definition: ic.cc:2586
KeyedAccessGrowMode
Definition: objects.h:142
MUST_USE_RESULT MaybeObject * Store(State state, StrictModeFlag strict_mode, Handle< Object > object, Handle< Object > name, Handle< Object > value, bool force_generic)
Definition: ic.cc:1866
#define CONST_NAME(name)
Definition: ic.h:72
void patch(Code *code)
Definition: ic.cc:2301
RelocInfo::Mode ComputeMode()
Definition: ic.cc:267
static Address AddressFromUtilityId(UtilityId id)
Definition: ic.cc:2698
static Handle< Code > GetUninitialized(Token::Value op)
Definition: ic.cc:2565
void check(i::Vector< const char > string)
static InlineCacheHolderFlag GetCodeCacheForObject(Object *object, JSObject *holder)
Definition: ic-inl.h:103
bool IsContextual(Handle< Object > receiver)
Definition: ic.h:115
static void GenerateInitialize(MacroAssembler *masm)
Definition: ic.h:660
Failure * ReferenceError(const char *type, Handle< String > name)
Definition: ic.cc:291
static void GeneratePreMonomorphic(MacroAssembler *masm)
Definition: ic.h:496
static void GenerateMiss(MacroAssembler *masm, int argc)
Definition: ic.h:311
Handle< Code > ComputeMonomorphicStubWithoutMapCheck(Handle< Map > receiver_map, StrictModeFlag strict_mode, KeyedAccessGrowMode grow_mode)
Definition: ic.cc:1688
static void Clear(Address address)
Definition: ic.cc:344
virtual bool IsGeneric() const
Definition: ic.h:677
static void GenerateNormal(MacroAssembler *masm)
static void GenerateInitialize(MacroAssembler *masm, int argc)
Definition: ic.h:307
static void GenerateMiss(MacroAssembler *masm, bool force_generic)