• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2006-2009 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 
33 namespace v8 {
34 namespace internal {
35 
36 
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.
39 #define IC_UTIL_LIST(ICU)                             \
40   ICU(LoadIC_Miss)                                    \
41   ICU(KeyedLoadIC_Miss)                               \
42   ICU(CallIC_Miss)                                    \
43   ICU(KeyedCallIC_Miss)                               \
44   ICU(StoreIC_Miss)                                   \
45   ICU(StoreIC_ArrayLength)                            \
46   ICU(SharedStoreIC_ExtendStorage)                    \
47   ICU(KeyedStoreIC_Miss)                              \
48   /* Utilities for IC stubs. */                       \
49   ICU(LoadCallbackProperty)                           \
50   ICU(StoreCallbackProperty)                          \
51   ICU(LoadPropertyWithInterceptorOnly)                \
52   ICU(LoadPropertyWithInterceptorForLoad)             \
53   ICU(LoadPropertyWithInterceptorForCall)             \
54   ICU(KeyedLoadPropertyWithInterceptor)               \
55   ICU(StoreInterceptorProperty)                       \
56   ICU(TypeRecordingBinaryOp_Patch)                    \
57   ICU(CompareIC_Miss)
58 //
59 // IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC,
60 // and KeyedStoreIC.
61 //
62 class IC {
63  public:
64 
65   // The ids for utility called from the generated code.
66   enum UtilityId {
67   #define CONST_NAME(name) k##name,
68     IC_UTIL_LIST(CONST_NAME)
69   #undef CONST_NAME
70     kUtilityCount
71   };
72 
73   // Looks up the address of the named utility.
74   static Address AddressFromUtilityId(UtilityId id);
75 
76   // Alias the inline cache state type to make the IC code more readable.
77   typedef InlineCacheState State;
78 
79   // The IC code is either invoked with no extra frames on the stack
80   // or with a single extra frame for supporting calls.
81   enum FrameDepth {
82     NO_EXTRA_FRAME = 0,
83     EXTRA_CALL_FRAME = 1
84   };
85 
86   // Construct the IC structure with the given number of extra
87   // JavaScript frames on the stack.
88   IC(FrameDepth depth, Isolate* isolate);
89 
90   // Get the call-site target; used for determining the state.
target()91   Code* target() { return GetTargetAtAddress(address()); }
92   inline Address address();
93 
94   // Compute the current IC state based on the target stub, receiver and name.
95   static State StateFrom(Code* target, Object* receiver, Object* name);
96 
97   // Clear the inline cache to initial state.
98   static void Clear(Address address);
99 
100   // Computes the reloc info for this IC. This is a fairly expensive
101   // operation as it has to search through the heap to find the code
102   // object that contains this IC site.
103   RelocInfo::Mode ComputeMode();
104 
105   // Returns if this IC is for contextual (no explicit receiver)
106   // access to properties.
IsContextual(Handle<Object> receiver)107   bool IsContextual(Handle<Object> receiver) {
108     if (receiver->IsGlobalObject()) {
109       return SlowIsContextual();
110     } else {
111       ASSERT(!SlowIsContextual());
112       return false;
113     }
114   }
115 
SlowIsContextual()116   bool SlowIsContextual() {
117     return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
118   }
119 
120   // Determines which map must be used for keeping the code stub.
121   // These methods should not be called with undefined or null.
122   static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object,
123                                                             JSObject* holder);
124   static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object,
125                                                             JSObject* holder);
126   static inline JSObject* GetCodeCacheHolder(Object* object,
127                                              InlineCacheHolderFlag holder);
128 
129  protected:
fp()130   Address fp() const { return fp_; }
pc()131   Address pc() const { return *pc_address_; }
isolate()132   Isolate* isolate() const { return isolate_; }
133 
134 #ifdef ENABLE_DEBUGGER_SUPPORT
135   // Computes the address in the original code when the code running is
136   // containing break points (calls to DebugBreakXXX builtins).
137   Address OriginalCodeAddress();
138 #endif
139 
140   // Set the call-site target.
set_target(Code * code)141   void set_target(Code* code) { SetTargetAtAddress(address(), code); }
142 
143 #ifdef DEBUG
144   static void TraceIC(const char* type,
145                       Handle<Object> name,
146                       State old_state,
147                       Code* new_target,
148                       const char* extra_info = "");
149 #endif
150 
151   Failure* TypeError(const char* type,
152                      Handle<Object> object,
153                      Handle<Object> key);
154   Failure* ReferenceError(const char* type, Handle<String> name);
155 
156   // Access the target code for the given IC address.
157   static inline Code* GetTargetAtAddress(Address address);
158   static inline void SetTargetAtAddress(Address address, Code* target);
159 
160  private:
161   // Frame pointer for the frame that uses (calls) the IC.
162   Address fp_;
163 
164   // All access to the program counter of an IC structure is indirect
165   // to make the code GC safe. This feature is crucial since
166   // GetProperty and SetProperty are called and they in turn might
167   // invoke the garbage collector.
168   Address* pc_address_;
169 
170   Isolate* isolate_;
171 
172   DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
173 };
174 
175 
176 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you
177 // cannot make forward declarations to an enum.
178 class IC_Utility {
179  public:
IC_Utility(IC::UtilityId id)180   explicit IC_Utility(IC::UtilityId id)
181     : address_(IC::AddressFromUtilityId(id)), id_(id) {}
182 
address()183   Address address() const { return address_; }
184 
id()185   IC::UtilityId id() const { return id_; }
186  private:
187   Address address_;
188   IC::UtilityId id_;
189 };
190 
191 
192 class CallICBase: public IC {
193  protected:
CallICBase(Code::Kind kind,Isolate * isolate)194   CallICBase(Code::Kind kind, Isolate* isolate)
195       : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
196 
197  public:
198   MUST_USE_RESULT MaybeObject* LoadFunction(State state,
199                                             Code::ExtraICState extra_ic_state,
200                                             Handle<Object> object,
201                                             Handle<String> name);
202 
203  protected:
204   Code::Kind kind_;
205 
206   bool TryUpdateExtraICState(LookupResult* lookup,
207                              Handle<Object> object,
208                              Code::ExtraICState* extra_ic_state);
209 
210   MUST_USE_RESULT MaybeObject* ComputeMonomorphicStub(
211       LookupResult* lookup,
212       State state,
213       Code::ExtraICState extra_ic_state,
214       Handle<Object> object,
215       Handle<String> name);
216 
217   // Update the inline cache and the global stub cache based on the
218   // lookup result.
219   void UpdateCaches(LookupResult* lookup,
220                     State state,
221                     Code::ExtraICState extra_ic_state,
222                     Handle<Object> object,
223                     Handle<String> name);
224 
225   // Returns a JSFunction if the object can be called as a function,
226   // and patches the stack to be ready for the call.
227   // Otherwise, it returns the undefined value.
228   Object* TryCallAsFunction(Object* object);
229 
230   void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
231 
232   static void Clear(Address address, Code* target);
233   friend class IC;
234 };
235 
236 
237 class CallIC: public CallICBase {
238  public:
CallIC(Isolate * isolate)239   explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) {
240     ASSERT(target()->is_call_stub());
241   }
242 
243   // Code generator routines.
GenerateInitialize(MacroAssembler * masm,int argc)244   static void GenerateInitialize(MacroAssembler* masm, int argc) {
245     GenerateMiss(masm, argc);
246   }
247   static void GenerateMiss(MacroAssembler* masm, int argc);
248   static void GenerateMegamorphic(MacroAssembler* masm, int argc);
249   static void GenerateNormal(MacroAssembler* masm, int argc);
250 };
251 
252 
253 class KeyedCallIC: public CallICBase {
254  public:
KeyedCallIC(Isolate * isolate)255   explicit KeyedCallIC(Isolate* isolate)
256       : CallICBase(Code::KEYED_CALL_IC, isolate) {
257     ASSERT(target()->is_keyed_call_stub());
258   }
259 
260   MUST_USE_RESULT MaybeObject* LoadFunction(State state,
261                                             Handle<Object> object,
262                                             Handle<Object> key);
263 
264   // Code generator routines.
GenerateInitialize(MacroAssembler * masm,int argc)265   static void GenerateInitialize(MacroAssembler* masm, int argc) {
266     GenerateMiss(masm, argc);
267   }
268   static void GenerateMiss(MacroAssembler* masm, int argc);
269   static void GenerateMegamorphic(MacroAssembler* masm, int argc);
270   static void GenerateNormal(MacroAssembler* masm, int argc);
271 };
272 
273 
274 class LoadIC: public IC {
275  public:
LoadIC(Isolate * isolate)276   explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
277     ASSERT(target()->is_load_stub());
278   }
279 
280   MUST_USE_RESULT MaybeObject* Load(State state,
281                                     Handle<Object> object,
282                                     Handle<String> name);
283 
284   // Code generator routines.
GenerateInitialize(MacroAssembler * masm)285   static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
GeneratePreMonomorphic(MacroAssembler * masm)286   static void GeneratePreMonomorphic(MacroAssembler* masm) {
287     GenerateMiss(masm);
288   }
289   static void GenerateMiss(MacroAssembler* masm);
290   static void GenerateMegamorphic(MacroAssembler* masm);
291   static void GenerateNormal(MacroAssembler* masm);
292 
293   // Specialized code generator routines.
294   static void GenerateArrayLength(MacroAssembler* masm);
295   static void GenerateStringLength(MacroAssembler* masm,
296                                    bool support_wrappers);
297   static void GenerateFunctionPrototype(MacroAssembler* masm);
298 
299   // Clear the use of the inlined version.
300   static void ClearInlinedVersion(Address address);
301 
302   // The offset from the inlined patch site to the start of the
303   // inlined load instruction.  It is architecture-dependent, and not
304   // used on ARM.
305   static const int kOffsetToLoadInstruction;
306 
307  private:
308   // Update the inline cache and the global stub cache based on the
309   // lookup result.
310   void UpdateCaches(LookupResult* lookup,
311                     State state,
312                     Handle<Object> object,
313                     Handle<String> name);
314 
315   // Stub accessors.
megamorphic_stub()316   Code* megamorphic_stub() {
317     return isolate()->builtins()->builtin(
318         Builtins::kLoadIC_Megamorphic);
319   }
initialize_stub()320   static Code* initialize_stub() {
321     return Isolate::Current()->builtins()->builtin(
322         Builtins::kLoadIC_Initialize);
323   }
pre_monomorphic_stub()324   Code* pre_monomorphic_stub() {
325     return isolate()->builtins()->builtin(
326         Builtins::kLoadIC_PreMonomorphic);
327   }
328 
329   static void Clear(Address address, Code* target);
330 
331   static bool PatchInlinedLoad(Address address, Object* map, int index);
332 
333   static bool PatchInlinedContextualLoad(Address address,
334                                          Object* map,
335                                          Object* cell,
336                                          bool is_dont_delete);
337 
338   friend class IC;
339 };
340 
341 
342 class KeyedLoadIC: public IC {
343  public:
KeyedLoadIC(Isolate * isolate)344   explicit KeyedLoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
345     ASSERT(target()->is_keyed_load_stub());
346   }
347 
348   MUST_USE_RESULT MaybeObject* Load(State state,
349                                     Handle<Object> object,
350                                     Handle<Object> key);
351 
352   // Code generator routines.
353   static void GenerateMiss(MacroAssembler* masm);
354   static void GenerateRuntimeGetProperty(MacroAssembler* masm);
GenerateInitialize(MacroAssembler * masm)355   static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
GeneratePreMonomorphic(MacroAssembler * masm)356   static void GeneratePreMonomorphic(MacroAssembler* masm) {
357     GenerateMiss(masm);
358   }
359   static void GenerateGeneric(MacroAssembler* masm);
360   static void GenerateString(MacroAssembler* masm);
361 
362   static void GenerateIndexedInterceptor(MacroAssembler* masm);
363 
364   // Clear the use of the inlined version.
365   static void ClearInlinedVersion(Address address);
366 
367   // Bit mask to be tested against bit field for the cases when
368   // generic stub should go into slow case.
369   // Access check is necessary explicitly since generic stub does not perform
370   // map checks.
371   static const int kSlowCaseBitFieldMask =
372       (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
373 
374  private:
375   // Update the inline cache.
376   void UpdateCaches(LookupResult* lookup,
377                     State state,
378                     Handle<Object> object,
379                     Handle<String> name);
380 
381   // Stub accessors.
initialize_stub()382   static Code* initialize_stub() {
383     return Isolate::Current()->builtins()->builtin(
384         Builtins::kKeyedLoadIC_Initialize);
385   }
megamorphic_stub()386   Code* megamorphic_stub() {
387     return isolate()->builtins()->builtin(
388         Builtins::kKeyedLoadIC_Generic);
389   }
generic_stub()390   Code* generic_stub() {
391     return isolate()->builtins()->builtin(
392         Builtins::kKeyedLoadIC_Generic);
393   }
pre_monomorphic_stub()394   Code* pre_monomorphic_stub() {
395     return isolate()->builtins()->builtin(
396         Builtins::kKeyedLoadIC_PreMonomorphic);
397   }
string_stub()398   Code* string_stub() {
399     return isolate()->builtins()->builtin(
400         Builtins::kKeyedLoadIC_String);
401   }
402 
indexed_interceptor_stub()403   Code* indexed_interceptor_stub() {
404     return isolate()->builtins()->builtin(
405         Builtins::kKeyedLoadIC_IndexedInterceptor);
406   }
407 
408   static void Clear(Address address, Code* target);
409 
410   // Support for patching the map that is checked in an inlined
411   // version of keyed load.
412   static bool PatchInlinedLoad(Address address, Object* map);
413 
414   friend class IC;
415 };
416 
417 
418 class StoreIC: public IC {
419  public:
StoreIC(Isolate * isolate)420   explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
421     ASSERT(target()->is_store_stub());
422   }
423 
424   MUST_USE_RESULT MaybeObject* Store(State state,
425                                      StrictModeFlag strict_mode,
426                                      Handle<Object> object,
427                                      Handle<String> name,
428                                      Handle<Object> value);
429 
430   // Code generators for stub routines. Only called once at startup.
GenerateInitialize(MacroAssembler * masm)431   static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
432   static void GenerateMiss(MacroAssembler* masm);
433   static void GenerateMegamorphic(MacroAssembler* masm,
434                                   StrictModeFlag strict_mode);
435   static void GenerateArrayLength(MacroAssembler* masm);
436   static void GenerateNormal(MacroAssembler* masm);
437   static void GenerateGlobalProxy(MacroAssembler* masm,
438                                   StrictModeFlag strict_mode);
439 
440   // Clear the use of an inlined version.
441   static void ClearInlinedVersion(Address address);
442 
443   // The offset from the inlined patch site to the start of the
444   // inlined store instruction.
445   static const int kOffsetToStoreInstruction;
446 
447  private:
448   // Update the inline cache and the global stub cache based on the
449   // lookup result.
450   void UpdateCaches(LookupResult* lookup,
451                     State state,
452                     StrictModeFlag strict_mode,
453                     Handle<JSObject> receiver,
454                     Handle<String> name,
455                     Handle<Object> value);
456 
set_target(Code * code)457   void set_target(Code* code) {
458     // Strict mode must be preserved across IC patching.
459     ASSERT((code->extra_ic_state() & kStrictMode) ==
460            (target()->extra_ic_state() & kStrictMode));
461     IC::set_target(code);
462   }
463 
464   // Stub accessors.
megamorphic_stub()465   Code* megamorphic_stub() {
466     return isolate()->builtins()->builtin(
467         Builtins::kStoreIC_Megamorphic);
468   }
megamorphic_stub_strict()469   Code* megamorphic_stub_strict() {
470     return isolate()->builtins()->builtin(
471         Builtins::kStoreIC_Megamorphic_Strict);
472   }
initialize_stub()473   static Code* initialize_stub() {
474     return Isolate::Current()->builtins()->builtin(
475         Builtins::kStoreIC_Initialize);
476   }
initialize_stub_strict()477   static Code* initialize_stub_strict() {
478     return Isolate::Current()->builtins()->builtin(
479         Builtins::kStoreIC_Initialize_Strict);
480   }
global_proxy_stub()481   Code* global_proxy_stub() {
482     return isolate()->builtins()->builtin(
483         Builtins::kStoreIC_GlobalProxy);
484   }
global_proxy_stub_strict()485   Code* global_proxy_stub_strict() {
486     return isolate()->builtins()->builtin(
487         Builtins::kStoreIC_GlobalProxy_Strict);
488   }
489 
490   static void Clear(Address address, Code* target);
491 
492   // Support for patching the index and the map that is checked in an
493   // inlined version of the named store.
494   static bool PatchInlinedStore(Address address, Object* map, int index);
495 
496   friend class IC;
497 };
498 
499 
500 class KeyedStoreIC: public IC {
501  public:
KeyedStoreIC(Isolate * isolate)502   explicit KeyedStoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
503 
504   MUST_USE_RESULT MaybeObject* Store(State state,
505                                      StrictModeFlag strict_mode,
506                                      Handle<Object> object,
507                                      Handle<Object> name,
508                                      Handle<Object> value);
509 
510   // Code generators for stub routines.  Only called once at startup.
GenerateInitialize(MacroAssembler * masm)511   static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
512   static void GenerateMiss(MacroAssembler* masm);
513   static void GenerateRuntimeSetProperty(MacroAssembler* masm,
514                                          StrictModeFlag strict_mode);
515   static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
516 
517   // Clear the inlined version so the IC is always hit.
518   static void ClearInlinedVersion(Address address);
519 
520   // Restore the inlined version so the fast case can get hit.
521   static void RestoreInlinedVersion(Address address);
522 
523  private:
524   // Update the inline cache.
525   void UpdateCaches(LookupResult* lookup,
526                     State state,
527                     StrictModeFlag strict_mode,
528                     Handle<JSObject> receiver,
529                     Handle<String> name,
530                     Handle<Object> value);
531 
set_target(Code * code)532   void set_target(Code* code) {
533     // Strict mode must be preserved across IC patching.
534     ASSERT((code->extra_ic_state() & kStrictMode) ==
535            (target()->extra_ic_state() & kStrictMode));
536     IC::set_target(code);
537   }
538 
539   // Stub accessors.
initialize_stub()540   static Code* initialize_stub() {
541     return Isolate::Current()->builtins()->builtin(
542         Builtins::kKeyedStoreIC_Initialize);
543   }
megamorphic_stub()544   Code* megamorphic_stub() {
545     return isolate()->builtins()->builtin(
546         Builtins::kKeyedStoreIC_Generic);
547   }
initialize_stub_strict()548   static Code* initialize_stub_strict() {
549     return Isolate::Current()->builtins()->builtin(
550         Builtins::kKeyedStoreIC_Initialize_Strict);
551   }
megamorphic_stub_strict()552   Code* megamorphic_stub_strict() {
553     return isolate()->builtins()->builtin(
554         Builtins::kKeyedStoreIC_Generic_Strict);
555   }
generic_stub()556   Code* generic_stub() {
557     return isolate()->builtins()->builtin(
558         Builtins::kKeyedStoreIC_Generic);
559   }
generic_stub_strict()560   Code* generic_stub_strict() {
561     return isolate()->builtins()->builtin(
562         Builtins::kKeyedStoreIC_Generic_Strict);
563   }
564 
565   static void Clear(Address address, Code* target);
566 
567   // Support for patching the map that is checked in an inlined
568   // version of keyed store.
569   // The address is the patch point for the IC call
570   // (Assembler::kCallTargetAddressOffset before the end of
571   // the call/return address).
572   // The map is the new map that the inlined code should check against.
573   static bool PatchInlinedStore(Address address, Object* map);
574 
575   friend class IC;
576 };
577 
578 
579 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
580 class TRBinaryOpIC: public IC {
581  public:
582 
583   enum TypeInfo {
584     UNINITIALIZED,
585     SMI,
586     INT32,
587     HEAP_NUMBER,
588     ODDBALL,
589     STRING,  // Only used for addition operation.  At least one string operand.
590     GENERIC
591   };
592 
TRBinaryOpIC(Isolate * isolate)593   explicit TRBinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
594 
595   void patch(Code* code);
596 
597   static const char* GetName(TypeInfo type_info);
598 
599   static State ToState(TypeInfo type_info);
600 
601   static TypeInfo GetTypeInfo(Handle<Object> left, Handle<Object> right);
602 
603   static TypeInfo JoinTypes(TypeInfo x, TypeInfo y);
604 };
605 
606 
607 class CompareIC: public IC {
608  public:
609   enum State {
610     UNINITIALIZED,
611     SMIS,
612     HEAP_NUMBERS,
613     OBJECTS,
614     GENERIC
615   };
616 
CompareIC(Isolate * isolate,Token::Value op)617   CompareIC(Isolate* isolate, Token::Value op)
618       : IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
619 
620   // Update the inline cache for the given operands.
621   void UpdateCaches(Handle<Object> x, Handle<Object> y);
622 
623   // Factory method for getting an uninitialized compare stub.
624   static Handle<Code> GetUninitialized(Token::Value op);
625 
626   // Helper function for computing the condition for a compare operation.
627   static Condition ComputeCondition(Token::Value op);
628 
629   // Helper function for determining the state of a compare IC.
630   static State ComputeState(Code* target);
631 
632   static const char* GetStateName(State state);
633 
634  private:
635   State TargetState(State state, bool has_inlined_smi_code,
636                     Handle<Object> x, Handle<Object> y);
637 
strict()638   bool strict() const { return op_ == Token::EQ_STRICT; }
GetCondition()639   Condition GetCondition() const { return ComputeCondition(op_); }
GetState()640   State GetState() { return ComputeState(target()); }
641 
642   Token::Value op_;
643 };
644 
645 // Helper for TRBinaryOpIC and CompareIC.
646 void PatchInlinedSmiCode(Address address);
647 
648 } }  // namespace v8::internal
649 
650 #endif  // V8_IC_H_
651