blob: 56625525d472c9e633b55a124eb468c5ca6dccef [file] [log] [blame]
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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
Ben Murdochb0fe1622011-05-05 13:52:32 +010031#include "macro-assembler.h"
Ben Murdoch257744e2011-11-30 15:57:28 +000032#include "type-info.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000033
34namespace v8 {
35namespace internal {
36
Leon Clarkee46be812010-01-19 14:06:41 +000037
Steve Blocka7e24c12009-10-30 11:49:00 +000038// 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) \
Ben Murdoch257744e2011-11-30 15:57:28 +000043 ICU(KeyedLoadIC_MissForceGeneric) \
Steve Blocka7e24c12009-10-30 11:49:00 +000044 ICU(CallIC_Miss) \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +010045 ICU(KeyedCallIC_Miss) \
Steve Blocka7e24c12009-10-30 11:49:00 +000046 ICU(StoreIC_Miss) \
Steve Block6ded16b2010-05-10 14:33:55 +010047 ICU(StoreIC_ArrayLength) \
Steve Blocka7e24c12009-10-30 11:49:00 +000048 ICU(SharedStoreIC_ExtendStorage) \
49 ICU(KeyedStoreIC_Miss) \
Ben Murdoch257744e2011-11-30 15:57:28 +000050 ICU(KeyedStoreIC_MissForceGeneric) \
51 ICU(KeyedStoreIC_Slow) \
Steve Blocka7e24c12009-10-30 11:49:00 +000052 /* Utilities for IC stubs. */ \
53 ICU(LoadCallbackProperty) \
54 ICU(StoreCallbackProperty) \
55 ICU(LoadPropertyWithInterceptorOnly) \
56 ICU(LoadPropertyWithInterceptorForLoad) \
57 ICU(LoadPropertyWithInterceptorForCall) \
Andrei Popescu402d9372010-02-26 13:31:12 +000058 ICU(KeyedLoadPropertyWithInterceptor) \
Steve Block6ded16b2010-05-10 14:33:55 +010059 ICU(StoreInterceptorProperty) \
Ben Murdoch257744e2011-11-30 15:57:28 +000060 ICU(UnaryOp_Patch) \
61 ICU(BinaryOp_Patch) \
Ben Murdoch69a99ed2011-11-30 16:03:39 +000062 ICU(CompareIC_Miss) \
63 ICU(ToBoolean_Patch)
Steve Blocka7e24c12009-10-30 11:49:00 +000064//
65// IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC,
66// and KeyedStoreIC.
67//
68class IC {
69 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000070 // The ids for utility called from the generated code.
71 enum UtilityId {
72 #define CONST_NAME(name) k##name,
73 IC_UTIL_LIST(CONST_NAME)
74 #undef CONST_NAME
75 kUtilityCount
76 };
77
78 // Looks up the address of the named utility.
79 static Address AddressFromUtilityId(UtilityId id);
80
81 // Alias the inline cache state type to make the IC code more readable.
82 typedef InlineCacheState State;
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 {
87 NO_EXTRA_FRAME = 0,
88 EXTRA_CALL_FRAME = 1
89 };
90
91 // Construct the IC structure with the given number of extra
92 // JavaScript frames on the stack.
Steve Block44f0eee2011-05-26 01:26:41 +010093 IC(FrameDepth depth, Isolate* isolate);
Ben Murdochc7cc0282012-03-05 14:35:55 +000094 virtual ~IC() {}
Steve Blocka7e24c12009-10-30 11:49:00 +000095
96 // Get the call-site target; used for determining the state.
Ben Murdochc7cc0282012-03-05 14:35:55 +000097 Code* target() const { return GetTargetAtAddress(address()); }
98 inline Address address() const;
99
100 virtual bool IsGeneric() const { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000101
Steve Block6ded16b2010-05-10 14:33:55 +0100102 // Compute the current IC state based on the target stub, receiver and name.
103 static State StateFrom(Code* target, Object* receiver, Object* name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000104
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.
Leon Clarkee46be812010-01-19 14:06:41 +0000115 bool IsContextual(Handle<Object> receiver) {
116 if (receiver->IsGlobalObject()) {
117 return SlowIsContextual();
118 } else {
119 ASSERT(!SlowIsContextual());
120 return false;
121 }
122 }
123
124 bool SlowIsContextual() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000125 return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
126 }
127
Steve Block8defd9f2010-07-08 12:39:36 +0100128 // 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);
132 static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object,
133 JSObject* holder);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100134 static inline JSObject* GetCodeCacheHolder(Object* object,
135 InlineCacheHolderFlag holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000136
137 protected:
138 Address fp() const { return fp_; }
139 Address pc() const { return *pc_address_; }
Steve Block44f0eee2011-05-26 01:26:41 +0100140 Isolate* isolate() const { return isolate_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000141
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).
Ben Murdochc7cc0282012-03-05 14:35:55 +0000145 Address OriginalCodeAddress() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000146#endif
147
148 // Set the call-site target.
149 void set_target(Code* code) { SetTargetAtAddress(address(), code); }
150
151#ifdef DEBUG
Ben Murdochc7cc0282012-03-05 14:35:55 +0000152 char TransitionMarkFromState(IC::State state);
153
Ben Murdoch257744e2011-11-30 15:57:28 +0000154 void TraceIC(const char* type,
155 Handle<Object> name,
156 State old_state,
Ben Murdoch589d6972011-11-30 16:04:58 +0000157 Code* new_target);
Steve Blocka7e24c12009-10-30 11:49:00 +0000158#endif
159
Steve Block44f0eee2011-05-26 01:26:41 +0100160 Failure* TypeError(const char* type,
161 Handle<Object> object,
162 Handle<Object> key);
163 Failure* ReferenceError(const char* type, Handle<String> name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000164
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);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100168 static void PostPatching(Address address, Code* target, Code* old_target);
Steve Blocka7e24c12009-10-30 11:49:00 +0000169
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
Steve Block44f0eee2011-05-26 01:26:41 +0100180 Isolate* isolate_;
181
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 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.
188class IC_Utility {
189 public:
190 explicit IC_Utility(IC::UtilityId id)
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
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100202class CallICBase: public IC {
Ben Murdoch257744e2011-11-30 15:57:28 +0000203 public:
204 class Contextual: public BitField<bool, 0, 1> {};
205 class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
206
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000207 // Returns a JSFunction or a Failure.
John Reck59135872010-11-02 12:39:01 -0700208 MUST_USE_RESULT MaybeObject* LoadFunction(State state,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100209 Code::ExtraICState extra_ic_state,
John Reck59135872010-11-02 12:39:01 -0700210 Handle<Object> object,
211 Handle<String> name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000212
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100213 protected:
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000214 CallICBase(Code::Kind kind, Isolate* isolate)
215 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000216
Ben Murdochb8e0da22011-05-16 14:20:40 +0100217 bool TryUpdateExtraICState(LookupResult* lookup,
218 Handle<Object> object,
219 Code::ExtraICState* extra_ic_state);
220
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000221 // 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);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100227
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000228 // Update the inline cache and the global stub cache based on the lookup
229 // result.
Steve Blocka7e24c12009-10-30 11:49:00 +0000230 void UpdateCaches(LookupResult* lookup,
231 State state,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100232 Code::ExtraICState extra_ic_state,
Steve Blocka7e24c12009-10-30 11:49:00 +0000233 Handle<Object> object,
234 Handle<String> name);
235
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000236 // 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.
239 Handle<Object> TryCallAsFunction(Handle<Object> object);
Steve Blocka7e24c12009-10-30 11:49:00 +0000240
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100241 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
Leon Clarkee46be812010-01-19 14:06:41 +0000242
Steve Blocka7e24c12009-10-30 11:49:00 +0000243 static void Clear(Address address, Code* target);
Ben Murdoch257744e2011-11-30 15:57:28 +0000244
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000245 // 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
254 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
255 int argc,
256 Code::Kind kind,
257 Code::ExtraICState extra_state);
258
259 Code::Kind kind_;
260
Steve Blocka7e24c12009-10-30 11:49:00 +0000261 friend class IC;
262};
263
264
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100265class CallIC: public CallICBase {
266 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100267 explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) {
268 ASSERT(target()->is_call_stub());
269 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100270
271 // Code generator routines.
Ben Murdoch257744e2011-11-30 15:57:28 +0000272 static void GenerateInitialize(MacroAssembler* masm,
273 int argc,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000274 Code::ExtraICState extra_state) {
275 GenerateMiss(masm, argc, extra_state);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100276 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000277
Ben Murdoch257744e2011-11-30 15:57:28 +0000278 static void GenerateMiss(MacroAssembler* masm,
279 int argc,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000280 Code::ExtraICState extra_state) {
281 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state);
282 }
283
Ben Murdoch257744e2011-11-30 15:57:28 +0000284 static void GenerateMegamorphic(MacroAssembler* masm,
285 int argc,
286 Code::ExtraICState extra_ic_state);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000287
288 static void GenerateNormal(MacroAssembler* masm, int argc) {
289 CallICBase::GenerateNormal(masm, argc);
290 GenerateMiss(masm, argc, Code::kNoExtraICState);
291 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100292};
293
294
295class KeyedCallIC: public CallICBase {
296 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100297 explicit KeyedCallIC(Isolate* isolate)
298 : CallICBase(Code::KEYED_CALL_IC, isolate) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100299 ASSERT(target()->is_keyed_call_stub());
300 }
301
John Reck59135872010-11-02 12:39:01 -0700302 MUST_USE_RESULT MaybeObject* LoadFunction(State state,
303 Handle<Object> object,
304 Handle<Object> key);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100305
306 // Code generator routines.
307 static void GenerateInitialize(MacroAssembler* masm, int argc) {
308 GenerateMiss(masm, argc);
309 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000310
311 static void GenerateMiss(MacroAssembler* masm, int argc) {
312 CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss,
313 Code::kNoExtraICState);
314 }
315
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100316 static void GenerateMegamorphic(MacroAssembler* masm, int argc);
317 static void GenerateNormal(MacroAssembler* masm, int argc);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000318 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100319};
320
321
Steve Blocka7e24c12009-10-30 11:49:00 +0000322class LoadIC: public IC {
323 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100324 explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
325 ASSERT(target()->is_load_stub());
326 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000327
John Reck59135872010-11-02 12:39:01 -0700328 MUST_USE_RESULT MaybeObject* Load(State state,
329 Handle<Object> object,
330 Handle<String> name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000331
332 // Code generator routines.
Andrei Popescu402d9372010-02-26 13:31:12 +0000333 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
334 static void GeneratePreMonomorphic(MacroAssembler* masm) {
335 GenerateMiss(masm);
336 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000337 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);
Steve Block1e0659c2011-05-24 12:43:12 +0100343 static void GenerateStringLength(MacroAssembler* masm,
344 bool support_wrappers);
Steve Blocka7e24c12009-10-30 11:49:00 +0000345 static void GenerateFunctionPrototype(MacroAssembler* masm);
346
Steve Blocka7e24c12009-10-30 11:49:00 +0000347 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000348 // 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.
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000356 Handle<Code> megamorphic_stub() {
357 return isolate()->builtins()->LoadIC_Megamorphic();
Steve Blocka7e24c12009-10-30 11:49:00 +0000358 }
359 static Code* initialize_stub() {
Steve Block44f0eee2011-05-26 01:26:41 +0100360 return Isolate::Current()->builtins()->builtin(
361 Builtins::kLoadIC_Initialize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000362 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000363 Handle<Code> pre_monomorphic_stub() {
364 return isolate()->builtins()->LoadIC_PreMonomorphic();
Steve Blocka7e24c12009-10-30 11:49:00 +0000365 }
366
367 static void Clear(Address address, Code* target);
368
Steve Blocka7e24c12009-10-30 11:49:00 +0000369 friend class IC;
370};
371
372
Ben Murdoch257744e2011-11-30 15:57:28 +0000373class KeyedIC: public IC {
Steve Blocka7e24c12009-10-30 11:49:00 +0000374 public:
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000375 enum StubKind {
376 LOAD,
377 STORE_NO_TRANSITION,
378 STORE_TRANSITION_SMI_TO_OBJECT,
379 STORE_TRANSITION_SMI_TO_DOUBLE,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100380 STORE_TRANSITION_DOUBLE_TO_OBJECT,
381 STORE_AND_GROW_NO_TRANSITION,
382 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
383 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
384 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000385 };
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100386
387 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
388 STORE_NO_TRANSITION;
389 STATIC_ASSERT(kGrowICDelta ==
390 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
391 STORE_TRANSITION_SMI_TO_OBJECT);
392 STATIC_ASSERT(kGrowICDelta ==
393 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
394 STORE_TRANSITION_SMI_TO_DOUBLE);
395 STATIC_ASSERT(kGrowICDelta ==
396 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
397 STORE_TRANSITION_DOUBLE_TO_OBJECT);
398
Ben Murdoch257744e2011-11-30 15:57:28 +0000399 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
400 virtual ~KeyedIC() {}
401
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100402 static inline KeyedAccessGrowMode GetGrowModeFromStubKind(
403 StubKind stub_kind) {
404 return (stub_kind >= STORE_AND_GROW_NO_TRANSITION)
405 ? ALLOW_JSARRAY_GROWTH
406 : DO_NOT_ALLOW_JSARRAY_GROWTH;
407 }
408
409 static inline StubKind GetGrowStubKind(StubKind stub_kind) {
410 ASSERT(stub_kind != LOAD);
411 if (stub_kind < STORE_AND_GROW_NO_TRANSITION) {
412 stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) +
413 kGrowICDelta);
414 }
415 return stub_kind;
416 }
417
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000418 virtual Handle<Code> GetElementStubWithoutMapCheck(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000419 bool is_js_array,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100420 ElementsKind elements_kind,
421 KeyedAccessGrowMode grow_mode) = 0;
Ben Murdoch257744e2011-11-30 15:57:28 +0000422
423 protected:
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000424 virtual Handle<Code> string_stub() {
425 return Handle<Code>::null();
Ben Murdoch257744e2011-11-30 15:57:28 +0000426 }
427
428 virtual Code::Kind kind() const = 0;
429
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000430 Handle<Code> ComputeStub(Handle<JSObject> receiver,
431 StubKind stub_kind,
Ben Murdoch257744e2011-11-30 15:57:28 +0000432 StrictModeFlag strict_mode,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000433 Handle<Code> default_stub);
Ben Murdoch257744e2011-11-30 15:57:28 +0000434
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100435 virtual Handle<Code> ComputePolymorphicStub(
436 MapHandleList* receiver_maps,
437 StrictModeFlag strict_mode,
438 KeyedAccessGrowMode grow_mode) = 0;
Ben Murdoch257744e2011-11-30 15:57:28 +0000439
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000440 Handle<Code> ComputeMonomorphicStubWithoutMapCheck(
441 Handle<Map> receiver_map,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100442 StrictModeFlag strict_mode,
443 KeyedAccessGrowMode grow_mode);
Ben Murdoch257744e2011-11-30 15:57:28 +0000444
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000445 private:
446 void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
447
448 Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver,
449 StubKind stub_kind,
Ben Murdoch257744e2011-11-30 15:57:28 +0000450 StrictModeFlag strict_mode,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000451 Handle<Code> default_stub);
452
453 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
454 StubKind stub_kind);
455
456 static bool IsTransitionStubKind(StubKind stub_kind) {
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100457 return stub_kind > STORE_NO_TRANSITION &&
458 stub_kind != STORE_AND_GROW_NO_TRANSITION;
459 }
460
461 static bool IsGrowStubKind(StubKind stub_kind) {
462 return stub_kind >= STORE_AND_GROW_NO_TRANSITION;
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000463 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000464};
465
466
467class KeyedLoadIC: public KeyedIC {
468 public:
469 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100470 ASSERT(target()->is_keyed_load_stub());
471 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000472
John Reck59135872010-11-02 12:39:01 -0700473 MUST_USE_RESULT MaybeObject* Load(State state,
474 Handle<Object> object,
Ben Murdoch257744e2011-11-30 15:57:28 +0000475 Handle<Object> key,
476 bool force_generic_stub);
Steve Blocka7e24c12009-10-30 11:49:00 +0000477
478 // Code generator routines.
Ben Murdoch257744e2011-11-30 15:57:28 +0000479 static void GenerateMiss(MacroAssembler* masm, bool force_generic);
Andrei Popescu402d9372010-02-26 13:31:12 +0000480 static void GenerateRuntimeGetProperty(MacroAssembler* masm);
Ben Murdoch257744e2011-11-30 15:57:28 +0000481 static void GenerateInitialize(MacroAssembler* masm) {
482 GenerateMiss(masm, false);
483 }
Andrei Popescu402d9372010-02-26 13:31:12 +0000484 static void GeneratePreMonomorphic(MacroAssembler* masm) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000485 GenerateMiss(masm, false);
Andrei Popescu402d9372010-02-26 13:31:12 +0000486 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000487 static void GenerateGeneric(MacroAssembler* masm);
Leon Clarkee46be812010-01-19 14:06:41 +0000488 static void GenerateString(MacroAssembler* masm);
Andrei Popescu402d9372010-02-26 13:31:12 +0000489 static void GenerateIndexedInterceptor(MacroAssembler* masm);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000490 static void GenerateNonStrictArguments(MacroAssembler* masm);
Steve Block3ce2e202009-11-05 08:53:23 +0000491
Leon Clarked91b9f72010-01-27 17:25:45 +0000492 // Bit mask to be tested against bit field for the cases when
493 // generic stub should go into slow case.
494 // Access check is necessary explicitly since generic stub does not perform
495 // map checks.
496 static const int kSlowCaseBitFieldMask =
497 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
498
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000499 virtual Handle<Code> GetElementStubWithoutMapCheck(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000500 bool is_js_array,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100501 ElementsKind elements_kind,
502 KeyedAccessGrowMode grow_mode);
Ben Murdoch257744e2011-11-30 15:57:28 +0000503
Ben Murdochc7cc0282012-03-05 14:35:55 +0000504 virtual bool IsGeneric() const {
505 return target() == *generic_stub();
506 }
507
Ben Murdoch257744e2011-11-30 15:57:28 +0000508 protected:
509 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
510
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000511 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100512 StrictModeFlag strict_mode,
513 KeyedAccessGrowMode grow_mode);
Ben Murdoch257744e2011-11-30 15:57:28 +0000514
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000515 virtual Handle<Code> string_stub() {
516 return isolate()->builtins()->KeyedLoadIC_String();
Ben Murdoch257744e2011-11-30 15:57:28 +0000517 }
518
Steve Block6ded16b2010-05-10 14:33:55 +0100519 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000520 // Update the inline cache.
521 void UpdateCaches(LookupResult* lookup,
522 State state,
523 Handle<Object> object,
524 Handle<String> name);
525
526 // Stub accessors.
527 static Code* initialize_stub() {
Steve Block44f0eee2011-05-26 01:26:41 +0100528 return Isolate::Current()->builtins()->builtin(
529 Builtins::kKeyedLoadIC_Initialize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000530 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000531 Handle<Code> megamorphic_stub() {
532 return isolate()->builtins()->KeyedLoadIC_Generic();
Steve Blocka7e24c12009-10-30 11:49:00 +0000533 }
Ben Murdochc7cc0282012-03-05 14:35:55 +0000534 Handle<Code> generic_stub() const {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000535 return isolate()->builtins()->KeyedLoadIC_Generic();
Steve Blocka7e24c12009-10-30 11:49:00 +0000536 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000537 Handle<Code> pre_monomorphic_stub() {
538 return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
Steve Blocka7e24c12009-10-30 11:49:00 +0000539 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000540 Handle<Code> indexed_interceptor_stub() {
541 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
Andrei Popescu402d9372010-02-26 13:31:12 +0000542 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000543 Handle<Code> non_strict_arguments_stub() {
544 return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000545 }
Andrei Popescu402d9372010-02-26 13:31:12 +0000546
Steve Blocka7e24c12009-10-30 11:49:00 +0000547 static void Clear(Address address, Code* target);
548
Steve Blocka7e24c12009-10-30 11:49:00 +0000549 friend class IC;
550};
551
552
553class StoreIC: public IC {
554 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100555 explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {
556 ASSERT(target()->is_store_stub());
557 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000558
John Reck59135872010-11-02 12:39:01 -0700559 MUST_USE_RESULT MaybeObject* Store(State state,
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100560 StrictModeFlag strict_mode,
John Reck59135872010-11-02 12:39:01 -0700561 Handle<Object> object,
562 Handle<String> name,
563 Handle<Object> value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000564
565 // Code generators for stub routines. Only called once at startup.
Leon Clarke4515c472010-02-03 11:58:03 +0000566 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000567 static void GenerateMiss(MacroAssembler* masm);
Steve Block1e0659c2011-05-24 12:43:12 +0100568 static void GenerateMegamorphic(MacroAssembler* masm,
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100569 StrictModeFlag strict_mode);
Steve Block6ded16b2010-05-10 14:33:55 +0100570 static void GenerateArrayLength(MacroAssembler* masm);
Steve Block8defd9f2010-07-08 12:39:36 +0100571 static void GenerateNormal(MacroAssembler* masm);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100572 static void GenerateGlobalProxy(MacroAssembler* masm,
573 StrictModeFlag strict_mode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000574
575 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000576 // Update the inline cache and the global stub cache based on the
577 // lookup result.
578 void UpdateCaches(LookupResult* lookup,
Steve Block1e0659c2011-05-24 12:43:12 +0100579 State state,
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100580 StrictModeFlag strict_mode,
Steve Block1e0659c2011-05-24 12:43:12 +0100581 Handle<JSObject> receiver,
Steve Blocka7e24c12009-10-30 11:49:00 +0000582 Handle<String> name,
583 Handle<Object> value);
584
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100585 void set_target(Code* code) {
586 // Strict mode must be preserved across IC patching.
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100587 ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
588 Code::GetStrictMode(target()->extra_ic_state()));
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100589 IC::set_target(code);
590 }
591
Steve Blocka7e24c12009-10-30 11:49:00 +0000592 // Stub accessors.
Steve Block44f0eee2011-05-26 01:26:41 +0100593 Code* megamorphic_stub() {
594 return isolate()->builtins()->builtin(
595 Builtins::kStoreIC_Megamorphic);
Steve Blocka7e24c12009-10-30 11:49:00 +0000596 }
Steve Block44f0eee2011-05-26 01:26:41 +0100597 Code* megamorphic_stub_strict() {
598 return isolate()->builtins()->builtin(
599 Builtins::kStoreIC_Megamorphic_Strict);
Steve Block1e0659c2011-05-24 12:43:12 +0100600 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000601 static Code* initialize_stub() {
Steve Block44f0eee2011-05-26 01:26:41 +0100602 return Isolate::Current()->builtins()->builtin(
603 Builtins::kStoreIC_Initialize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000604 }
Steve Block1e0659c2011-05-24 12:43:12 +0100605 static Code* initialize_stub_strict() {
Steve Block44f0eee2011-05-26 01:26:41 +0100606 return Isolate::Current()->builtins()->builtin(
607 Builtins::kStoreIC_Initialize_Strict);
Steve Block1e0659c2011-05-24 12:43:12 +0100608 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000609 Handle<Code> global_proxy_stub() {
610 return isolate()->builtins()->StoreIC_GlobalProxy();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100611 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000612 Handle<Code> global_proxy_stub_strict() {
613 return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
Steve Block1e0659c2011-05-24 12:43:12 +0100614 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000615
616 static void Clear(Address address, Code* target);
Kristian Monsen50ef84f2010-07-29 15:18:00 +0100617
Steve Blocka7e24c12009-10-30 11:49:00 +0000618 friend class IC;
619};
620
621
Ben Murdoch257744e2011-11-30 15:57:28 +0000622class KeyedStoreIC: public KeyedIC {
Steve Blocka7e24c12009-10-30 11:49:00 +0000623 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000624 explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) {
625 ASSERT(target()->is_keyed_store_stub());
626 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000627
John Reck59135872010-11-02 12:39:01 -0700628 MUST_USE_RESULT MaybeObject* Store(State state,
Ben Murdoch257744e2011-11-30 15:57:28 +0000629 StrictModeFlag strict_mode,
John Reck59135872010-11-02 12:39:01 -0700630 Handle<Object> object,
631 Handle<Object> name,
Ben Murdoch257744e2011-11-30 15:57:28 +0000632 Handle<Object> value,
633 bool force_generic);
Steve Blocka7e24c12009-10-30 11:49:00 +0000634
635 // Code generators for stub routines. Only called once at startup.
Ben Murdoch257744e2011-11-30 15:57:28 +0000636 static void GenerateInitialize(MacroAssembler* masm) {
637 GenerateMiss(masm, false);
638 }
639 static void GenerateMiss(MacroAssembler* masm, bool force_generic);
640 static void GenerateSlow(MacroAssembler* masm);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100641 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
642 StrictModeFlag strict_mode);
643 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000644 static void GenerateNonStrictArguments(MacroAssembler* masm);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000645 static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm);
646 static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm);
Steve Blocka7e24c12009-10-30 11:49:00 +0000647
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000648 virtual Handle<Code> GetElementStubWithoutMapCheck(
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000649 bool is_js_array,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100650 ElementsKind elements_kind,
651 KeyedAccessGrowMode grow_mode);
Steve Block053d10c2011-06-13 19:13:29 +0100652
Ben Murdochc7cc0282012-03-05 14:35:55 +0000653 virtual bool IsGeneric() const {
654 return target() == *generic_stub() ||
655 target() == *generic_stub_strict();
656 }
657
Ben Murdoch257744e2011-11-30 15:57:28 +0000658 protected:
659 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
660
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000661 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100662 StrictModeFlag strict_mode,
663 KeyedAccessGrowMode grow_mode);
Ben Murdoch257744e2011-11-30 15:57:28 +0000664
665 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000666 // Update the inline cache.
667 void UpdateCaches(LookupResult* lookup,
668 State state,
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100669 StrictModeFlag strict_mode,
Steve Blocka7e24c12009-10-30 11:49:00 +0000670 Handle<JSObject> receiver,
671 Handle<String> name,
672 Handle<Object> value);
673
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100674 void set_target(Code* code) {
675 // Strict mode must be preserved across IC patching.
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100676 ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
677 Code::GetStrictMode(target()->extra_ic_state()));
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100678 IC::set_target(code);
679 }
680
Steve Blocka7e24c12009-10-30 11:49:00 +0000681 // Stub accessors.
682 static Code* initialize_stub() {
Steve Block44f0eee2011-05-26 01:26:41 +0100683 return Isolate::Current()->builtins()->builtin(
684 Builtins::kKeyedStoreIC_Initialize);
685 }
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100686 static Code* initialize_stub_strict() {
Steve Block44f0eee2011-05-26 01:26:41 +0100687 return Isolate::Current()->builtins()->builtin(
688 Builtins::kKeyedStoreIC_Initialize_Strict);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100689 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000690 Handle<Code> megamorphic_stub() {
691 return isolate()->builtins()->KeyedStoreIC_Generic();
Steve Blocka7e24c12009-10-30 11:49:00 +0000692 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000693 Handle<Code> megamorphic_stub_strict() {
694 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100695 }
Ben Murdochc7cc0282012-03-05 14:35:55 +0000696 Handle<Code> generic_stub() const {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000697 return isolate()->builtins()->KeyedStoreIC_Generic();
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100698 }
Ben Murdochc7cc0282012-03-05 14:35:55 +0000699 Handle<Code> generic_stub_strict() const {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000700 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
701 }
702 Handle<Code> non_strict_arguments_stub() {
703 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000704 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000705
706 static void Clear(Address address, Code* target);
707
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100708 StubKind GetStubKind(Handle<JSObject> receiver,
709 Handle<Object> key,
710 Handle<Object> value);
711
Steve Blocka7e24c12009-10-30 11:49:00 +0000712 friend class IC;
713};
714
715
Ben Murdoch257744e2011-11-30 15:57:28 +0000716class UnaryOpIC: public IC {
717 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000718 // sorted: increasingly more unspecific (ignoring UNINITIALIZED)
719 // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead.
720 enum TypeInfo {
721 UNINITIALIZED,
722 SMI,
723 HEAP_NUMBER,
724 GENERIC
725 };
726
727 explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
728
729 void patch(Code* code);
730
731 static const char* GetName(TypeInfo type_info);
732
733 static State ToState(TypeInfo type_info);
734
735 static TypeInfo GetTypeInfo(Handle<Object> operand);
736
737 static TypeInfo ComputeNewType(TypeInfo type, TypeInfo previous);
738};
739
740
Ben Murdochb0fe1622011-05-05 13:52:32 +0100741// Type Recording BinaryOpIC, that records the types of the inputs and outputs.
Ben Murdoch257744e2011-11-30 15:57:28 +0000742class BinaryOpIC: public IC {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100743 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100744 enum TypeInfo {
745 UNINITIALIZED,
746 SMI,
747 INT32,
748 HEAP_NUMBER,
Steve Block44f0eee2011-05-26 01:26:41 +0100749 ODDBALL,
Ben Murdoch257744e2011-11-30 15:57:28 +0000750 BOTH_STRING, // Only used for addition operation.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100751 STRING, // Only used for addition operation. At least one string operand.
752 GENERIC
753 };
754
Ben Murdoch257744e2011-11-30 15:57:28 +0000755 explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100756
757 void patch(Code* code);
758
759 static const char* GetName(TypeInfo type_info);
760
761 static State ToState(TypeInfo type_info);
762
763 static TypeInfo GetTypeInfo(Handle<Object> left, Handle<Object> right);
764
765 static TypeInfo JoinTypes(TypeInfo x, TypeInfo y);
766};
767
768
769class CompareIC: public IC {
770 public:
771 enum State {
772 UNINITIALIZED,
773 SMIS,
774 HEAP_NUMBERS,
Ben Murdoch257744e2011-11-30 15:57:28 +0000775 SYMBOLS,
776 STRINGS,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100777 OBJECTS,
Ben Murdochc7cc0282012-03-05 14:35:55 +0000778 KNOWN_OBJECTS,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100779 GENERIC
780 };
781
Steve Block44f0eee2011-05-26 01:26:41 +0100782 CompareIC(Isolate* isolate, Token::Value op)
783 : IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100784
785 // Update the inline cache for the given operands.
786 void UpdateCaches(Handle<Object> x, Handle<Object> y);
787
788 // Factory method for getting an uninitialized compare stub.
789 static Handle<Code> GetUninitialized(Token::Value op);
790
791 // Helper function for computing the condition for a compare operation.
792 static Condition ComputeCondition(Token::Value op);
793
794 // Helper function for determining the state of a compare IC.
795 static State ComputeState(Code* target);
796
797 static const char* GetStateName(State state);
798
799 private:
800 State TargetState(State state, bool has_inlined_smi_code,
801 Handle<Object> x, Handle<Object> y);
802
803 bool strict() const { return op_ == Token::EQ_STRICT; }
804 Condition GetCondition() const { return ComputeCondition(op_); }
805 State GetState() { return ComputeState(target()); }
806
807 Token::Value op_;
808};
809
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000810
811class ToBooleanIC: public IC {
812 public:
813 explicit ToBooleanIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
814
815 void patch(Code* code);
816};
817
818
Ben Murdoch257744e2011-11-30 15:57:28 +0000819// Helper for BinaryOpIC and CompareIC.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100820void PatchInlinedSmiCode(Address address);
821
Steve Blocka7e24c12009-10-30 11:49:00 +0000822} } // namespace v8::internal
823
824#endif // V8_IC_H_