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

Side by Side Diff: src/ic/ic.h

Issue 483683005: Move IC code into a subdir and move ic-compilation related code from stub-cache into ic-compiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix BUILD.gn Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic/ia32/stub-cache-ia32.cc ('k') | src/ic/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_IC_H_ 5 #ifndef V8_IC_H_
6 #define V8_IC_H_ 6 #define V8_IC_H_
7 7
8 #include "src/macro-assembler.h" 8 #include "src/macro-assembler.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 26 matching lines...) Expand all
37 ICU(CompareNilIC_Miss) \ 37 ICU(CompareNilIC_Miss) \
38 ICU(Unreachable) \ 38 ICU(Unreachable) \
39 ICU(ToBooleanIC_Miss) 39 ICU(ToBooleanIC_Miss)
40 // 40 //
41 // IC is the base class for LoadIC, StoreIC, KeyedLoadIC, and KeyedStoreIC. 41 // IC is the base class for LoadIC, StoreIC, KeyedLoadIC, and KeyedStoreIC.
42 // 42 //
43 class IC { 43 class IC {
44 public: 44 public:
45 // The ids for utility called from the generated code. 45 // The ids for utility called from the generated code.
46 enum UtilityId { 46 enum UtilityId {
47 #define CONST_NAME(name) k##name, 47 #define CONST_NAME(name) k##name,
48 IC_UTIL_LIST(CONST_NAME) 48 IC_UTIL_LIST(CONST_NAME)
49 #undef CONST_NAME 49 #undef CONST_NAME
50 kUtilityCount 50 kUtilityCount
51 }; 51 };
52 52
53 // Looks up the address of the named utility. 53 // Looks up the address of the named utility.
54 static Address AddressFromUtilityId(UtilityId id); 54 static Address AddressFromUtilityId(UtilityId id);
55 55
56 // Alias the inline cache state type to make the IC code more readable. 56 // Alias the inline cache state type to make the IC code more readable.
57 typedef InlineCacheState State; 57 typedef InlineCacheState State;
58 58
59 // The IC code is either invoked with no extra frames on the stack 59 // The IC code is either invoked with no extra frames on the stack
60 // or with a single extra frame for supporting calls. 60 // or with a single extra frame for supporting calls.
61 enum FrameDepth { 61 enum FrameDepth { NO_EXTRA_FRAME = 0, EXTRA_CALL_FRAME = 1 };
62 NO_EXTRA_FRAME = 0,
63 EXTRA_CALL_FRAME = 1
64 };
65 62
66 // Construct the IC structure with the given number of extra 63 // Construct the IC structure with the given number of extra
67 // JavaScript frames on the stack. 64 // JavaScript frames on the stack.
68 IC(FrameDepth depth, Isolate* isolate); 65 IC(FrameDepth depth, Isolate* isolate);
69 virtual ~IC() {} 66 virtual ~IC() {}
70 67
71 State state() const { return state_; } 68 State state() const { return state_; }
72 inline Address address() const; 69 inline Address address() const;
73 70
74 // Compute the current IC state based on the target stub, receiver and name. 71 // Compute the current IC state based on the target stub, receiver and name.
75 void UpdateState(Handle<Object> receiver, Handle<Object> name); 72 void UpdateState(Handle<Object> receiver, Handle<Object> name);
76 73
77 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); 74 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name);
78 void MarkPrototypeFailure(Handle<Object> name) { 75 void MarkPrototypeFailure(Handle<Object> name) {
79 DCHECK(IsNameCompatibleWithPrototypeFailure(name)); 76 DCHECK(IsNameCompatibleWithPrototypeFailure(name));
80 state_ = PROTOTYPE_FAILURE; 77 state_ = PROTOTYPE_FAILURE;
81 } 78 }
82 79
83 // If the stub contains weak maps then this function adds the stub to 80 // If the stub contains weak maps then this function adds the stub to
84 // the dependent code array of each weak map. 81 // the dependent code array of each weak map.
85 static void RegisterWeakMapDependency(Handle<Code> stub); 82 static void RegisterWeakMapDependency(Handle<Code> stub);
86 83
87 // This function is called when a weak map in the stub is dying, 84 // This function is called when a weak map in the stub is dying,
88 // invalidates the stub by setting maps in it to undefined. 85 // invalidates the stub by setting maps in it to undefined.
89 static void InvalidateMaps(Code* stub); 86 static void InvalidateMaps(Code* stub);
90 87
91 // Clear the inline cache to initial state. 88 // Clear the inline cache to initial state.
92 static void Clear(Isolate* isolate, 89 static void Clear(Isolate* isolate, Address address,
93 Address address,
94 ConstantPoolArray* constant_pool); 90 ConstantPoolArray* constant_pool);
95 91
96 #ifdef DEBUG 92 #ifdef DEBUG
97 bool IsLoadStub() const { 93 bool IsLoadStub() const {
98 return target()->is_load_stub() || target()->is_keyed_load_stub(); 94 return target()->is_load_stub() || target()->is_keyed_load_stub();
99 } 95 }
100 96
101 bool IsStoreStub() const { 97 bool IsStoreStub() const {
102 return target()->is_store_stub() || target()->is_keyed_store_stub(); 98 return target()->is_store_stub() || target()->is_keyed_store_stub();
103 } 99 }
104 100
105 bool IsCallStub() const { 101 bool IsCallStub() const { return target()->is_call_stub(); }
106 return target()->is_call_stub();
107 }
108 #endif 102 #endif
109 103
110 template <class TypeClass> 104 template <class TypeClass>
111 static JSFunction* GetRootConstructor(TypeClass* type, 105 static JSFunction* GetRootConstructor(TypeClass* type,
112 Context* native_context); 106 Context* native_context);
113 static inline Handle<Map> GetHandlerCacheHolder(HeapType* type, 107 static inline Handle<Map> GetHandlerCacheHolder(HeapType* type,
114 bool receiver_is_holder, 108 bool receiver_is_holder,
115 Isolate* isolate, 109 Isolate* isolate,
116 CacheHolderFlag* flag); 110 CacheHolderFlag* flag);
117 static inline Handle<Map> GetICCacheHolder(HeapType* type, Isolate* isolate, 111 static inline Handle<Map> GetICCacheHolder(HeapType* type, Isolate* isolate,
(...skipping 26 matching lines...) Expand all
144 Isolate* isolate() const { return isolate_; } 138 Isolate* isolate() const { return isolate_; }
145 139
146 // Get the shared function info of the caller. 140 // Get the shared function info of the caller.
147 SharedFunctionInfo* GetSharedFunctionInfo() const; 141 SharedFunctionInfo* GetSharedFunctionInfo() const;
148 // Get the code object of the caller. 142 // Get the code object of the caller.
149 Code* GetCode() const; 143 Code* GetCode() const;
150 // Get the original (non-breakpointed) code object of the caller. 144 // Get the original (non-breakpointed) code object of the caller.
151 Code* GetOriginalCode() const; 145 Code* GetOriginalCode() const;
152 146
153 // Set the call-site target. 147 // Set the call-site target.
154 void set_target(Code* code) { 148 inline void set_target(Code* code);
155 #ifdef VERIFY_HEAP
156 code->VerifyEmbeddedObjectsDependency();
157 #endif
158 SetTargetAtAddress(address(), code, constant_pool());
159 target_set_ = true;
160 }
161
162 bool is_target_set() { return target_set_; } 149 bool is_target_set() { return target_set_; }
163 150
164 char TransitionMarkFromState(IC::State state); 151 char TransitionMarkFromState(IC::State state);
165 void TraceIC(const char* type, Handle<Object> name); 152 void TraceIC(const char* type, Handle<Object> name);
166 void TraceIC(const char* type, Handle<Object> name, State old_state, 153 void TraceIC(const char* type, Handle<Object> name, State old_state,
167 State new_state); 154 State new_state);
168 155
169 MaybeHandle<Object> TypeError(const char* type, 156 MaybeHandle<Object> TypeError(const char* type, Handle<Object> object,
170 Handle<Object> object,
171 Handle<Object> key); 157 Handle<Object> key);
172 MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name); 158 MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name);
173 159
174 // Access the target code for the given IC address. 160 // Access the target code for the given IC address.
175 static inline Code* GetTargetAtAddress(Address address, 161 static inline Code* GetTargetAtAddress(Address address,
176 ConstantPoolArray* constant_pool); 162 ConstantPoolArray* constant_pool);
177 static inline void SetTargetAtAddress(Address address, 163 static inline void SetTargetAtAddress(Address address, Code* target,
178 Code* target,
179 ConstantPoolArray* constant_pool); 164 ConstantPoolArray* constant_pool);
180 static void OnTypeFeedbackChanged(Isolate* isolate, Address address, 165 static void OnTypeFeedbackChanged(Isolate* isolate, Address address,
181 State old_state, State new_state, 166 State old_state, State new_state,
182 bool target_remains_ic_stub); 167 bool target_remains_ic_stub);
183 static void PostPatching(Address address, Code* target, Code* old_target); 168 static void PostPatching(Address address, Code* target, Code* old_target);
184 169
185 // Compute the handler either by compiling or by retrieving a cached version. 170 // Compute the handler either by compiling or by retrieving a cached version.
186 Handle<Code> ComputeHandler(LookupIterator* lookup, 171 Handle<Code> ComputeHandler(LookupIterator* lookup,
187 Handle<Object> value = Handle<Code>::null()); 172 Handle<Object> value = Handle<Code>::null());
188 virtual Handle<Code> CompileHandler(LookupIterator* lookup, 173 virtual Handle<Code> CompileHandler(LookupIterator* lookup,
(...skipping 19 matching lines...) Expand all
208 } 193 }
209 virtual Handle<Code> megamorphic_stub() { 194 virtual Handle<Code> megamorphic_stub() {
210 UNREACHABLE(); 195 UNREACHABLE();
211 return Handle<Code>::null(); 196 return Handle<Code>::null();
212 } 197 }
213 198
214 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 199 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
215 Handle<String> name); 200 Handle<String> name);
216 201
217 ExtraICState extra_ic_state() const { return extra_ic_state_; } 202 ExtraICState extra_ic_state() const { return extra_ic_state_; }
218 void set_extra_ic_state(ExtraICState state) { 203 void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; }
219 extra_ic_state_ = state;
220 }
221 204
222 Handle<HeapType> receiver_type() { return receiver_type_; } 205 Handle<HeapType> receiver_type() { return receiver_type_; }
223 void update_receiver_type(Handle<Object> receiver) { 206 void update_receiver_type(Handle<Object> receiver) {
224 receiver_type_ = CurrentTypeOf(receiver, isolate_); 207 receiver_type_ = CurrentTypeOf(receiver, isolate_);
225 } 208 }
226 209
227 void TargetMaps(MapHandleList* list) { 210 void TargetMaps(MapHandleList* list) {
228 FindTargetMaps(); 211 FindTargetMaps();
229 for (int i = 0; i < target_maps_.length(); i++) { 212 for (int i = 0; i < target_maps_.length(); i++) {
230 list->Add(target_maps_.at(i)); 213 list->Add(target_maps_.at(i));
231 } 214 }
232 } 215 }
233 216
234 void TargetTypes(TypeHandleList* list) { 217 void TargetTypes(TypeHandleList* list) {
235 FindTargetMaps(); 218 FindTargetMaps();
236 for (int i = 0; i < target_maps_.length(); i++) { 219 for (int i = 0; i < target_maps_.length(); i++) {
237 list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_)); 220 list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_));
238 } 221 }
239 } 222 }
240 223
241 Map* FirstTargetMap() { 224 Map* FirstTargetMap() {
242 FindTargetMaps(); 225 FindTargetMaps();
243 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; 226 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
244 } 227 }
245 228
246 protected: 229 protected:
247 void UpdateTarget() { 230 inline void UpdateTarget();
248 target_ = handle(raw_target(), isolate_);
249 }
250 231
251 private: 232 private:
252 Code* raw_target() const { 233 inline Code* raw_target() const;
253 return GetTargetAtAddress(address(), constant_pool());
254 }
255 inline ConstantPoolArray* constant_pool() const; 234 inline ConstantPoolArray* constant_pool() const;
256 inline ConstantPoolArray* raw_constant_pool() const; 235 inline ConstantPoolArray* raw_constant_pool() const;
257 236
258 void FindTargetMaps() { 237 void FindTargetMaps() {
259 if (target_maps_set_) return; 238 if (target_maps_set_) return;
260 target_maps_set_ = true; 239 target_maps_set_ = true;
261 if (state_ == MONOMORPHIC) { 240 if (state_ == MONOMORPHIC) {
262 Map* map = target_->FindFirstMap(); 241 Map* map = target_->FindFirstMap();
263 if (map != NULL) target_maps_.Add(handle(map)); 242 if (map != NULL) target_maps_.Add(handle(map));
264 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { 243 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
(...skipping 30 matching lines...) Expand all
295 274
296 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); 275 DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
297 }; 276 };
298 277
299 278
300 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you 279 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you
301 // cannot make forward declarations to an enum. 280 // cannot make forward declarations to an enum.
302 class IC_Utility { 281 class IC_Utility {
303 public: 282 public:
304 explicit IC_Utility(IC::UtilityId id) 283 explicit IC_Utility(IC::UtilityId id)
305 : address_(IC::AddressFromUtilityId(id)), id_(id) {} 284 : address_(IC::AddressFromUtilityId(id)), id_(id) {}
306 285
307 Address address() const { return address_; } 286 Address address() const { return address_; }
308 287
309 IC::UtilityId id() const { return id_; } 288 IC::UtilityId id() const { return id_; }
289
310 private: 290 private:
311 Address address_; 291 Address address_;
312 IC::UtilityId id_; 292 IC::UtilityId id_;
313 }; 293 };
314 294
315 295
316 class CallIC: public IC { 296 class CallIC : public IC {
317 public: 297 public:
318 enum CallType { METHOD, FUNCTION }; 298 enum CallType { METHOD, FUNCTION };
319 299
320 class State V8_FINAL BASE_EMBEDDED { 300 class State V8_FINAL BASE_EMBEDDED {
321 public: 301 public:
322 explicit State(ExtraICState extra_ic_state); 302 explicit State(ExtraICState extra_ic_state);
323 303
324 State(int argc, CallType call_type) 304 State(int argc, CallType call_type) : argc_(argc), call_type_(call_type) {}
325 : argc_(argc), call_type_(call_type) {
326 }
327 305
328 ExtraICState GetExtraICState() const; 306 ExtraICState GetExtraICState() const;
329 307
330 static void GenerateAheadOfTime( 308 static void GenerateAheadOfTime(Isolate*,
331 Isolate*, void (*Generate)(Isolate*, const State&)); 309 void (*Generate)(Isolate*, const State&));
332 310
333 int arg_count() const { return argc_; } 311 int arg_count() const { return argc_; }
334 CallType call_type() const { return call_type_; } 312 CallType call_type() const { return call_type_; }
335 313
336 bool CallAsMethod() const { return call_type_ == METHOD; } 314 bool CallAsMethod() const { return call_type_ == METHOD; }
337 315
338 private: 316 private:
339 class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {}; 317 class ArgcBits : public BitField<int, 0, Code::kArgumentsBits> {};
340 class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {}; 318 class CallTypeBits : public BitField<CallType, Code::kArgumentsBits, 1> {};
341 319
342 const int argc_; 320 const int argc_;
343 const CallType call_type_; 321 const CallType call_type_;
344 }; 322 };
345 323
346 explicit CallIC(Isolate* isolate) 324 explicit CallIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
347 : IC(EXTRA_CALL_FRAME, isolate) {
348 }
349 325
350 void PatchMegamorphic(Handle<Object> function, Handle<FixedArray> vector, 326 void PatchMegamorphic(Handle<Object> function, Handle<FixedArray> vector,
351 Handle<Smi> slot); 327 Handle<Smi> slot);
352 328
353 void HandleMiss(Handle<Object> receiver, 329 void HandleMiss(Handle<Object> receiver, Handle<Object> function,
354 Handle<Object> function, 330 Handle<FixedArray> vector, Handle<Smi> slot);
355 Handle<FixedArray> vector,
356 Handle<Smi> slot);
357 331
358 // Returns true if a custom handler was installed. 332 // Returns true if a custom handler was installed.
359 bool DoCustomHandler(Handle<Object> receiver, 333 bool DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
360 Handle<Object> function, 334 Handle<FixedArray> vector, Handle<Smi> slot,
361 Handle<FixedArray> vector,
362 Handle<Smi> slot,
363 const State& state); 335 const State& state);
364 336
365 // Code generator routines. 337 // Code generator routines.
366 static Handle<Code> initialize_stub(Isolate* isolate, 338 static Handle<Code> initialize_stub(Isolate* isolate, int argc,
367 int argc,
368 CallType call_type); 339 CallType call_type);
369 340
370 static void Clear(Isolate* isolate, Address address, Code* target, 341 static void Clear(Isolate* isolate, Address address, Code* target,
371 ConstantPoolArray* constant_pool); 342 ConstantPoolArray* constant_pool);
372 343
373 private: 344 private:
374 inline IC::State FeedbackToState(Handle<FixedArray> vector, 345 inline IC::State FeedbackToState(Handle<FixedArray> vector,
375 Handle<Smi> slot) const; 346 Handle<Smi> slot) const;
376 }; 347 };
377 348
378 349
379 OStream& operator<<(OStream& os, const CallIC::State& s); 350 OStream& operator<<(OStream& os, const CallIC::State& s);
380 351
381 352
382 class LoadIC: public IC { 353 class LoadIC : public IC {
383 public: 354 public:
384 enum ParameterIndices { 355 enum ParameterIndices { kReceiverIndex, kNameIndex, kParameterCount };
385 kReceiverIndex,
386 kNameIndex,
387 kParameterCount
388 };
389 static const Register ReceiverRegister(); 356 static const Register ReceiverRegister();
390 static const Register NameRegister(); 357 static const Register NameRegister();
391 358
392 // With flag vector-ics, there is an additional argument. And for calls from 359 // With flag vector-ics, there is an additional argument. And for calls from
393 // crankshaft, yet another. 360 // crankshaft, yet another.
394 static const Register SlotRegister(); 361 static const Register SlotRegister();
395 static const Register VectorRegister(); 362 static const Register VectorRegister();
396 363
397 class State V8_FINAL BASE_EMBEDDED { 364 class State V8_FINAL BASE_EMBEDDED {
398 public: 365 public:
399 explicit State(ExtraICState extra_ic_state) 366 explicit State(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
400 : state_(extra_ic_state) {}
401 367
402 explicit State(ContextualMode mode) 368 explicit State(ContextualMode mode)
403 : state_(ContextualModeBits::encode(mode)) {} 369 : state_(ContextualModeBits::encode(mode)) {}
404 370
405 ExtraICState GetExtraICState() const { return state_; } 371 ExtraICState GetExtraICState() const { return state_; }
406 372
407 ContextualMode contextual_mode() const { 373 ContextualMode contextual_mode() const {
408 return ContextualModeBits::decode(state_); 374 return ContextualModeBits::decode(state_);
409 } 375 }
410 376
411 private: 377 private:
412 class ContextualModeBits: public BitField<ContextualMode, 0, 1> {}; 378 class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
413 STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0); 379 STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
414 380
415 const ExtraICState state_; 381 const ExtraICState state_;
416 }; 382 };
417 383
418 static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) { 384 static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) {
419 return State(contextual_mode).GetExtraICState(); 385 return State(contextual_mode).GetExtraICState();
420 } 386 }
421 387
422 static ContextualMode GetContextualMode(ExtraICState state) { 388 static ContextualMode GetContextualMode(ExtraICState state) {
423 return State(state).contextual_mode(); 389 return State(state).contextual_mode();
424 } 390 }
425 391
426 ContextualMode contextual_mode() const { 392 ContextualMode contextual_mode() const {
427 return GetContextualMode(extra_ic_state()); 393 return GetContextualMode(extra_ic_state());
428 } 394 }
429 395
430 explicit LoadIC(FrameDepth depth, Isolate* isolate) 396 explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
431 : IC(depth, isolate) {
432 DCHECK(IsLoadStub()); 397 DCHECK(IsLoadStub());
433 } 398 }
434 399
435 // Returns if this IC is for contextual (no explicit receiver) 400 // Returns if this IC is for contextual (no explicit receiver)
436 // access to properties. 401 // access to properties.
437 bool IsUndeclaredGlobal(Handle<Object> receiver) { 402 bool IsUndeclaredGlobal(Handle<Object> receiver) {
438 if (receiver->IsGlobalObject()) { 403 if (receiver->IsGlobalObject()) {
439 return contextual_mode() == CONTEXTUAL; 404 return contextual_mode() == CONTEXTUAL;
440 } else { 405 } else {
441 DCHECK(contextual_mode() != CONTEXTUAL); 406 DCHECK(contextual_mode() != CONTEXTUAL);
(...skipping 11 matching lines...) Expand all
453 static void GenerateNormal(MacroAssembler* masm); 418 static void GenerateNormal(MacroAssembler* masm);
454 static void GenerateRuntimeGetProperty(MacroAssembler* masm); 419 static void GenerateRuntimeGetProperty(MacroAssembler* masm);
455 420
456 static Handle<Code> initialize_stub(Isolate* isolate, 421 static Handle<Code> initialize_stub(Isolate* isolate,
457 ExtraICState extra_state); 422 ExtraICState extra_state);
458 423
459 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, 424 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
460 Handle<Name> name); 425 Handle<Name> name);
461 426
462 protected: 427 protected:
463 void set_target(Code* code) { 428 inline void set_target(Code* code);
464 // The contextual mode must be preserved across IC patching.
465 DCHECK(GetContextualMode(code->extra_ic_state()) ==
466 GetContextualMode(target()->extra_ic_state()));
467
468 IC::set_target(code);
469 }
470 429
471 Handle<Code> slow_stub() const { 430 Handle<Code> slow_stub() const {
472 if (kind() == Code::LOAD_IC) { 431 if (kind() == Code::LOAD_IC) {
473 return isolate()->builtins()->LoadIC_Slow(); 432 return isolate()->builtins()->LoadIC_Slow();
474 } else { 433 } else {
475 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); 434 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
476 return isolate()->builtins()->KeyedLoadIC_Slow(); 435 return isolate()->builtins()->KeyedLoadIC_Slow();
477 } 436 }
478 } 437 }
479 438
480 virtual Handle<Code> megamorphic_stub(); 439 virtual Handle<Code> megamorphic_stub();
481 440
482 // Update the inline cache and the global stub cache based on the 441 // Update the inline cache and the global stub cache based on the
483 // lookup result. 442 // lookup result.
484 void UpdateCaches(LookupIterator* lookup); 443 void UpdateCaches(LookupIterator* lookup);
485 444
486 virtual Handle<Code> CompileHandler(LookupIterator* lookup, 445 virtual Handle<Code> CompileHandler(LookupIterator* lookup,
487 Handle<Object> unused, 446 Handle<Object> unused,
488 CacheHolderFlag cache_holder); 447 CacheHolderFlag cache_holder);
489 448
490 private: 449 private:
491 virtual Handle<Code> pre_monomorphic_stub() const; 450 virtual Handle<Code> pre_monomorphic_stub() const;
492 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, 451 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
493 ExtraICState extra_state); 452 ExtraICState extra_state);
494 453
495 Handle<Code> SimpleFieldLoad(FieldIndex index); 454 Handle<Code> SimpleFieldLoad(FieldIndex index);
496 455
497 static void Clear(Isolate* isolate, 456 static void Clear(Isolate* isolate, Address address, Code* target,
498 Address address,
499 Code* target,
500 ConstantPoolArray* constant_pool); 457 ConstantPoolArray* constant_pool);
501 458
502 friend class IC; 459 friend class IC;
503 }; 460 };
504 461
505 462
506 class KeyedLoadIC: public LoadIC { 463 class KeyedLoadIC : public LoadIC {
507 public: 464 public:
508 explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate) 465 explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate)
509 : LoadIC(depth, isolate) { 466 : LoadIC(depth, isolate) {
510 DCHECK(target()->is_keyed_load_stub()); 467 DCHECK(target()->is_keyed_load_stub());
511 } 468 }
512 469
513 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, 470 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
514 Handle<Object> key); 471 Handle<Object> key);
515 472
516 // Code generator routines. 473 // Code generator routines.
(...skipping 29 matching lines...) Expand all
546 Handle<Code> indexed_interceptor_stub() { 503 Handle<Code> indexed_interceptor_stub() {
547 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor(); 504 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
548 } 505 }
549 Handle<Code> sloppy_arguments_stub() { 506 Handle<Code> sloppy_arguments_stub() {
550 return isolate()->builtins()->KeyedLoadIC_SloppyArguments(); 507 return isolate()->builtins()->KeyedLoadIC_SloppyArguments();
551 } 508 }
552 Handle<Code> string_stub() { 509 Handle<Code> string_stub() {
553 return isolate()->builtins()->KeyedLoadIC_String(); 510 return isolate()->builtins()->KeyedLoadIC_String();
554 } 511 }
555 512
556 static void Clear(Isolate* isolate, 513 static void Clear(Isolate* isolate, Address address, Code* target,
557 Address address,
558 Code* target,
559 ConstantPoolArray* constant_pool); 514 ConstantPoolArray* constant_pool);
560 515
561 friend class IC; 516 friend class IC;
562 }; 517 };
563 518
564 519
565 class StoreIC: public IC { 520 class StoreIC : public IC {
566 public: 521 public:
567 class StrictModeState: public BitField<StrictMode, 1, 1> {}; 522 class StrictModeState : public BitField<StrictMode, 1, 1> {};
568 static ExtraICState ComputeExtraICState(StrictMode flag) { 523 static ExtraICState ComputeExtraICState(StrictMode flag) {
569 return StrictModeState::encode(flag); 524 return StrictModeState::encode(flag);
570 } 525 }
571 static StrictMode GetStrictMode(ExtraICState state) { 526 static StrictMode GetStrictMode(ExtraICState state) {
572 return StrictModeState::decode(state); 527 return StrictModeState::decode(state);
573 } 528 }
574 529
575 // For convenience, a statically declared encoding of strict mode extra 530 // For convenience, a statically declared encoding of strict mode extra
576 // IC state. 531 // IC state.
577 static const ExtraICState kStrictModeState = 532 static const ExtraICState kStrictModeState = 1 << StrictModeState::kShift;
578 1 << StrictModeState::kShift;
579 533
580 enum ParameterIndices { 534 enum ParameterIndices {
581 kReceiverIndex, 535 kReceiverIndex,
582 kNameIndex, 536 kNameIndex,
583 kValueIndex, 537 kValueIndex,
584 kParameterCount 538 kParameterCount
585 }; 539 };
586 static const Register ReceiverRegister(); 540 static const Register ReceiverRegister();
587 static const Register NameRegister(); 541 static const Register NameRegister();
588 static const Register ValueRegister(); 542 static const Register ValueRegister();
589 543
590 StoreIC(FrameDepth depth, Isolate* isolate) 544 StoreIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
591 : IC(depth, isolate) {
592 DCHECK(IsStoreStub()); 545 DCHECK(IsStoreStub());
593 } 546 }
594 547
595 StrictMode strict_mode() const { 548 StrictMode strict_mode() const {
596 return StrictModeState::decode(extra_ic_state()); 549 return StrictModeState::decode(extra_ic_state());
597 } 550 }
598 551
599 // Code generators for stub routines. Only called once at startup. 552 // Code generators for stub routines. Only called once at startup.
600 static void GenerateSlow(MacroAssembler* masm); 553 static void GenerateSlow(MacroAssembler* masm);
601 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 554 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
602 static void GeneratePreMonomorphic(MacroAssembler* masm) { 555 static void GeneratePreMonomorphic(MacroAssembler* masm) {
603 GenerateMiss(masm); 556 GenerateMiss(masm);
604 } 557 }
605 static void GenerateMiss(MacroAssembler* masm); 558 static void GenerateMiss(MacroAssembler* masm);
606 static void GenerateMegamorphic(MacroAssembler* masm); 559 static void GenerateMegamorphic(MacroAssembler* masm);
607 static void GenerateNormal(MacroAssembler* masm); 560 static void GenerateNormal(MacroAssembler* masm);
608 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 561 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
609 StrictMode strict_mode); 562 StrictMode strict_mode);
610 563
611 static Handle<Code> initialize_stub(Isolate* isolate, 564 static Handle<Code> initialize_stub(Isolate* isolate, StrictMode strict_mode);
612 StrictMode strict_mode);
613 565
614 MUST_USE_RESULT MaybeHandle<Object> Store( 566 MUST_USE_RESULT MaybeHandle<Object> Store(
615 Handle<Object> object, 567 Handle<Object> object, Handle<Name> name, Handle<Object> value,
616 Handle<Name> name,
617 Handle<Object> value,
618 JSReceiver::StoreFromKeyed store_mode = 568 JSReceiver::StoreFromKeyed store_mode =
619 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); 569 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
620 570
621 bool LookupForWrite(LookupIterator* it, Handle<Object> value, 571 bool LookupForWrite(LookupIterator* it, Handle<Object> value,
622 JSReceiver::StoreFromKeyed store_mode); 572 JSReceiver::StoreFromKeyed store_mode);
623 573
624 protected: 574 protected:
625 virtual Handle<Code> megamorphic_stub(); 575 virtual Handle<Code> megamorphic_stub();
626 576
627 // Stub accessors. 577 // Stub accessors.
(...skipping 12 matching lines...) Expand all
640 590
641 // Update the inline cache and the global stub cache based on the 591 // Update the inline cache and the global stub cache based on the
642 // lookup result. 592 // lookup result.
643 void UpdateCaches(LookupIterator* lookup, Handle<Object> value, 593 void UpdateCaches(LookupIterator* lookup, Handle<Object> value,
644 JSReceiver::StoreFromKeyed store_mode); 594 JSReceiver::StoreFromKeyed store_mode);
645 virtual Handle<Code> CompileHandler(LookupIterator* lookup, 595 virtual Handle<Code> CompileHandler(LookupIterator* lookup,
646 Handle<Object> value, 596 Handle<Object> value,
647 CacheHolderFlag cache_holder); 597 CacheHolderFlag cache_holder);
648 598
649 private: 599 private:
650 void set_target(Code* code) { 600 inline void set_target(Code* code);
651 // Strict mode must be preserved across IC patching.
652 DCHECK(GetStrictMode(code->extra_ic_state()) ==
653 GetStrictMode(target()->extra_ic_state()));
654 IC::set_target(code);
655 }
656 601
657 static void Clear(Isolate* isolate, 602 static void Clear(Isolate* isolate, Address address, Code* target,
658 Address address,
659 Code* target,
660 ConstantPoolArray* constant_pool); 603 ConstantPoolArray* constant_pool);
661 604
662 friend class IC; 605 friend class IC;
663 }; 606 };
664 607
665 608
666 enum KeyedStoreCheckMap { 609 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap };
667 kDontCheckMap,
668 kCheckMap
669 };
670 610
671 611
672 enum KeyedStoreIncrementLength { 612 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength };
673 kDontIncrementLength,
674 kIncrementLength
675 };
676 613
677 614
678 class KeyedStoreIC: public StoreIC { 615 class KeyedStoreIC : public StoreIC {
679 public: 616 public:
680 // ExtraICState bits (building on IC) 617 // ExtraICState bits (building on IC)
681 // ExtraICState bits 618 // ExtraICState bits
682 class ExtraICStateKeyedAccessStoreMode: 619 class ExtraICStateKeyedAccessStoreMode
683 public BitField<KeyedAccessStoreMode, 2, 4> {}; // NOLINT 620 : public BitField<KeyedAccessStoreMode, 2, 4> {}; // NOLINT
684 621
685 static ExtraICState ComputeExtraICState(StrictMode flag, 622 static ExtraICState ComputeExtraICState(StrictMode flag,
686 KeyedAccessStoreMode mode) { 623 KeyedAccessStoreMode mode) {
687 return StrictModeState::encode(flag) | 624 return StrictModeState::encode(flag) |
688 ExtraICStateKeyedAccessStoreMode::encode(mode); 625 ExtraICStateKeyedAccessStoreMode::encode(mode);
689 } 626 }
690 627
691 static KeyedAccessStoreMode GetKeyedAccessStoreMode( 628 static KeyedAccessStoreMode GetKeyedAccessStoreMode(
692 ExtraICState extra_state) { 629 ExtraICState extra_state) {
693 return ExtraICStateKeyedAccessStoreMode::decode(extra_state); 630 return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
694 } 631 }
695 632
696 // The map register isn't part of the normal call specification, but 633 // The map register isn't part of the normal call specification, but
697 // ElementsTransitionAndStoreStub, used in polymorphic keyed store 634 // ElementsTransitionAndStoreStub, used in polymorphic keyed store
698 // stub implementations requires it to be initialized. 635 // stub implementations requires it to be initialized.
699 static const Register MapRegister(); 636 static const Register MapRegister();
700 637
701 KeyedStoreIC(FrameDepth depth, Isolate* isolate) 638 KeyedStoreIC(FrameDepth depth, Isolate* isolate) : StoreIC(depth, isolate) {
702 : StoreIC(depth, isolate) {
703 DCHECK(target()->is_keyed_store_stub()); 639 DCHECK(target()->is_keyed_store_stub());
704 } 640 }
705 641
706 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, 642 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object,
707 Handle<Object> name, 643 Handle<Object> name,
708 Handle<Object> value); 644 Handle<Object> value);
709 645
710 // Code generators for stub routines. Only called once at startup. 646 // Code generators for stub routines. Only called once at startup.
711 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 647 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
712 static void GeneratePreMonomorphic(MacroAssembler* masm) { 648 static void GeneratePreMonomorphic(MacroAssembler* masm) {
(...skipping 26 matching lines...) Expand all
739 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 675 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
740 } else { 676 } else {
741 return isolate()->builtins()->KeyedStoreIC_Generic(); 677 return isolate()->builtins()->KeyedStoreIC_Generic();
742 } 678 }
743 } 679 }
744 680
745 Handle<Code> StoreElementStub(Handle<JSObject> receiver, 681 Handle<Code> StoreElementStub(Handle<JSObject> receiver,
746 KeyedAccessStoreMode store_mode); 682 KeyedAccessStoreMode store_mode);
747 683
748 private: 684 private:
749 void set_target(Code* code) { 685 inline void set_target(Code* code);
750 // Strict mode must be preserved across IC patching.
751 DCHECK(GetStrictMode(code->extra_ic_state()) == strict_mode());
752 IC::set_target(code);
753 }
754 686
755 // Stub accessors. 687 // Stub accessors.
756 virtual Handle<Code> generic_stub() const { 688 virtual Handle<Code> generic_stub() const {
757 if (strict_mode() == STRICT) { 689 if (strict_mode() == STRICT) {
758 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 690 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
759 } else { 691 } else {
760 return isolate()->builtins()->KeyedStoreIC_Generic(); 692 return isolate()->builtins()->KeyedStoreIC_Generic();
761 } 693 }
762 } 694 }
763 695
764 Handle<Code> sloppy_arguments_stub() { 696 Handle<Code> sloppy_arguments_stub() {
765 return isolate()->builtins()->KeyedStoreIC_SloppyArguments(); 697 return isolate()->builtins()->KeyedStoreIC_SloppyArguments();
766 } 698 }
767 699
768 static void Clear(Isolate* isolate, 700 static void Clear(Isolate* isolate, Address address, Code* target,
769 Address address,
770 Code* target,
771 ConstantPoolArray* constant_pool); 701 ConstantPoolArray* constant_pool);
772 702
773 KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver, 703 KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
774 Handle<Object> key, 704 Handle<Object> key, Handle<Object> value);
775 Handle<Object> value);
776 705
777 Handle<Map> ComputeTransitionedMap(Handle<Map> map, 706 Handle<Map> ComputeTransitionedMap(Handle<Map> map,
778 KeyedAccessStoreMode store_mode); 707 KeyedAccessStoreMode store_mode);
779 708
780 friend class IC; 709 friend class IC;
781 }; 710 };
782 711
783 712
784 // Mode to overwrite BinaryExpression values. 713 // Mode to overwrite BinaryExpression values.
785 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; 714 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
786 715
787 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. 716 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
788 class BinaryOpIC: public IC { 717 class BinaryOpIC : public IC {
789 public: 718 public:
790 class State V8_FINAL BASE_EMBEDDED { 719 class State V8_FINAL BASE_EMBEDDED {
791 public: 720 public:
792 State(Isolate* isolate, ExtraICState extra_ic_state); 721 State(Isolate* isolate, ExtraICState extra_ic_state);
793 722
794 State(Isolate* isolate, Token::Value op, OverwriteMode mode) 723 State(Isolate* isolate, Token::Value op, OverwriteMode mode)
795 : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE), 724 : op_(op),
796 result_kind_(NONE), isolate_(isolate) { 725 mode_(mode),
726 left_kind_(NONE),
727 right_kind_(NONE),
728 result_kind_(NONE),
729 isolate_(isolate) {
797 DCHECK_LE(FIRST_TOKEN, op); 730 DCHECK_LE(FIRST_TOKEN, op);
798 DCHECK_LE(op, LAST_TOKEN); 731 DCHECK_LE(op, LAST_TOKEN);
799 } 732 }
800 733
801 InlineCacheState GetICState() const { 734 InlineCacheState GetICState() const {
802 if (Max(left_kind_, right_kind_) == NONE) { 735 if (Max(left_kind_, right_kind_) == NONE) {
803 return ::v8::internal::UNINITIALIZED; 736 return ::v8::internal::UNINITIALIZED;
804 } 737 }
805 if (Max(left_kind_, right_kind_) == GENERIC) { 738 if (Max(left_kind_, right_kind_) == GENERIC) {
806 return ::v8::internal::MEGAMORPHIC; 739 return ::v8::internal::MEGAMORPHIC;
807 } 740 }
808 if (Min(left_kind_, right_kind_) == GENERIC) { 741 if (Min(left_kind_, right_kind_) == GENERIC) {
809 return ::v8::internal::GENERIC; 742 return ::v8::internal::GENERIC;
810 } 743 }
811 return ::v8::internal::MONOMORPHIC; 744 return ::v8::internal::MONOMORPHIC;
812 } 745 }
813 746
814 ExtraICState GetExtraICState() const; 747 ExtraICState GetExtraICState() const;
815 748
816 static void GenerateAheadOfTime( 749 static void GenerateAheadOfTime(Isolate*,
817 Isolate*, void (*Generate)(Isolate*, const State&)); 750 void (*Generate)(Isolate*, const State&));
818 751
819 bool CanReuseDoubleBox() const { 752 bool CanReuseDoubleBox() const {
820 return (result_kind_ > SMI && result_kind_ <= NUMBER) && 753 return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
821 ((mode_ == OVERWRITE_LEFT && 754 ((mode_ == OVERWRITE_LEFT && left_kind_ > SMI &&
822 left_kind_ > SMI && left_kind_ <= NUMBER) || 755 left_kind_ <= NUMBER) ||
823 (mode_ == OVERWRITE_RIGHT && 756 (mode_ == OVERWRITE_RIGHT && right_kind_ > SMI &&
824 right_kind_ > SMI && right_kind_ <= NUMBER)); 757 right_kind_ <= NUMBER));
825 } 758 }
826 759
827 // Returns true if the IC _could_ create allocation mementos. 760 // Returns true if the IC _could_ create allocation mementos.
828 bool CouldCreateAllocationMementos() const { 761 bool CouldCreateAllocationMementos() const {
829 if (left_kind_ == STRING || right_kind_ == STRING) { 762 if (left_kind_ == STRING || right_kind_ == STRING) {
830 DCHECK_EQ(Token::ADD, op_); 763 DCHECK_EQ(Token::ADD, op_);
831 return true; 764 return true;
832 } 765 }
833 return false; 766 return false;
834 } 767 }
835 768
836 // Returns true if the IC _should_ create allocation mementos. 769 // Returns true if the IC _should_ create allocation mementos.
837 bool ShouldCreateAllocationMementos() const { 770 bool ShouldCreateAllocationMementos() const {
838 return FLAG_allocation_site_pretenuring && 771 return FLAG_allocation_site_pretenuring &&
839 CouldCreateAllocationMementos(); 772 CouldCreateAllocationMementos();
840 } 773 }
841 774
842 bool HasSideEffects() const { 775 bool HasSideEffects() const {
843 return Max(left_kind_, right_kind_) == GENERIC; 776 return Max(left_kind_, right_kind_) == GENERIC;
844 } 777 }
845 778
846 // Returns true if the IC should enable the inline smi code (i.e. if either 779 // Returns true if the IC should enable the inline smi code (i.e. if either
847 // parameter may be a smi). 780 // parameter may be a smi).
848 bool UseInlinedSmiCode() const { 781 bool UseInlinedSmiCode() const {
849 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_); 782 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
850 } 783 }
851 784
852 static const int FIRST_TOKEN = Token::BIT_OR; 785 static const int FIRST_TOKEN = Token::BIT_OR;
853 static const int LAST_TOKEN = Token::MOD; 786 static const int LAST_TOKEN = Token::MOD;
854 787
855 Token::Value op() const { return op_; } 788 Token::Value op() const { return op_; }
856 OverwriteMode mode() const { return mode_; } 789 OverwriteMode mode() const { return mode_; }
857 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } 790 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
858 791
859 Type* GetLeftType(Zone* zone) const { 792 Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
860 return KindToType(left_kind_, zone);
861 }
862 Type* GetRightType(Zone* zone) const { 793 Type* GetRightType(Zone* zone) const {
863 return KindToType(right_kind_, zone); 794 return KindToType(right_kind_, zone);
864 } 795 }
865 Type* GetResultType(Zone* zone) const; 796 Type* GetResultType(Zone* zone) const;
866 797
867 void Update(Handle<Object> left, 798 void Update(Handle<Object> left, Handle<Object> right,
868 Handle<Object> right,
869 Handle<Object> result); 799 Handle<Object> result);
870 800
871 Isolate* isolate() const { return isolate_; } 801 Isolate* isolate() const { return isolate_; }
872 802
873 private: 803 private:
874 friend OStream& operator<<(OStream& os, const BinaryOpIC::State& s); 804 friend OStream& operator<<(OStream& os, const BinaryOpIC::State& s);
875 805
876 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; 806 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
877 807
878 Kind UpdateKind(Handle<Object> object, Kind kind) const; 808 Kind UpdateKind(Handle<Object> object, Kind kind) const;
879 809
880 static const char* KindToString(Kind kind); 810 static const char* KindToString(Kind kind);
881 static Type* KindToType(Kind kind, Zone* zone); 811 static Type* KindToType(Kind kind, Zone* zone);
882 static bool KindMaybeSmi(Kind kind) { 812 static bool KindMaybeSmi(Kind kind) {
883 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC; 813 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
884 } 814 }
885 815
886 // We truncate the last bit of the token. 816 // We truncate the last bit of the token.
887 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4)); 817 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
888 class OpField: public BitField<int, 0, 4> {}; 818 class OpField : public BitField<int, 0, 4> {};
889 class OverwriteModeField: public BitField<OverwriteMode, 4, 2> {}; 819 class OverwriteModeField : public BitField<OverwriteMode, 4, 2> {};
890 class ResultKindField: public BitField<Kind, 6, 3> {}; 820 class ResultKindField : public BitField<Kind, 6, 3> {};
891 class LeftKindField: public BitField<Kind, 9, 3> {}; 821 class LeftKindField : public BitField<Kind, 9, 3> {};
892 // When fixed right arg is set, we don't need to store the right kind. 822 // When fixed right arg is set, we don't need to store the right kind.
893 // Thus the two fields can overlap. 823 // Thus the two fields can overlap.
894 class HasFixedRightArgField: public BitField<bool, 12, 1> {}; 824 class HasFixedRightArgField : public BitField<bool, 12, 1> {};
895 class FixedRightArgValueField: public BitField<int, 13, 4> {}; 825 class FixedRightArgValueField : public BitField<int, 13, 4> {};
896 class RightKindField: public BitField<Kind, 13, 3> {}; 826 class RightKindField : public BitField<Kind, 13, 3> {};
897 827
898 Token::Value op_; 828 Token::Value op_;
899 OverwriteMode mode_; 829 OverwriteMode mode_;
900 Kind left_kind_; 830 Kind left_kind_;
901 Kind right_kind_; 831 Kind right_kind_;
902 Kind result_kind_; 832 Kind result_kind_;
903 Maybe<int> fixed_right_arg_; 833 Maybe<int> fixed_right_arg_;
904 Isolate* isolate_; 834 Isolate* isolate_;
905 }; 835 };
906 836
907 explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } 837 explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
908 838
909 static Builtins::JavaScript TokenToJSBuiltin(Token::Value op); 839 static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
910 840
911 MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site, 841 MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
912 Handle<Object> left, 842 Handle<Object> left,
913 Handle<Object> right) V8_WARN_UNUSED_RESULT; 843 Handle<Object> right) V8_WARN_UNUSED_RESULT;
914 }; 844 };
915 845
916 846
917 OStream& operator<<(OStream& os, const BinaryOpIC::State& s); 847 OStream& operator<<(OStream& os, const BinaryOpIC::State& s);
918 848
919 849
920 class CompareIC: public IC { 850 class CompareIC : public IC {
921 public: 851 public:
922 // The type/state lattice is defined by the following inequations: 852 // The type/state lattice is defined by the following inequations:
923 // UNINITIALIZED < ... 853 // UNINITIALIZED < ...
924 // ... < GENERIC 854 // ... < GENERIC
925 // SMI < NUMBER 855 // SMI < NUMBER
926 // INTERNALIZED_STRING < STRING 856 // INTERNALIZED_STRING < STRING
927 // KNOWN_OBJECT < OBJECT 857 // KNOWN_OBJECT < OBJECT
928 enum State { 858 enum State {
929 UNINITIALIZED, 859 UNINITIALIZED,
930 SMI, 860 SMI,
931 NUMBER, 861 NUMBER,
932 STRING, 862 STRING,
933 INTERNALIZED_STRING, 863 INTERNALIZED_STRING,
934 UNIQUE_NAME, // Symbol or InternalizedString 864 UNIQUE_NAME, // Symbol or InternalizedString
935 OBJECT, // JSObject 865 OBJECT, // JSObject
936 KNOWN_OBJECT, // JSObject with specific map (faster check) 866 KNOWN_OBJECT, // JSObject with specific map (faster check)
937 GENERIC 867 GENERIC
938 }; 868 };
939 869
940 static State NewInputState(State old_state, Handle<Object> value); 870 static State NewInputState(State old_state, Handle<Object> value);
941 871
942 static Type* StateToType(Zone* zone, 872 static Type* StateToType(Zone* zone, State state,
943 State state,
944 Handle<Map> map = Handle<Map>()); 873 Handle<Map> map = Handle<Map>());
945 874
946 static void StubInfoToType(uint32_t stub_key, Type** left_type, 875 static void StubInfoToType(uint32_t stub_key, Type** left_type,
947 Type** right_type, Type** overall_type, 876 Type** right_type, Type** overall_type,
948 Handle<Map> map, Zone* zone); 877 Handle<Map> map, Zone* zone);
949 878
950 CompareIC(Isolate* isolate, Token::Value op) 879 CompareIC(Isolate* isolate, Token::Value op)
951 : IC(EXTRA_CALL_FRAME, isolate), op_(op) { } 880 : IC(EXTRA_CALL_FRAME, isolate), op_(op) {}
952 881
953 // Update the inline cache for the given operands. 882 // Update the inline cache for the given operands.
954 Code* UpdateCaches(Handle<Object> x, Handle<Object> y); 883 Code* UpdateCaches(Handle<Object> x, Handle<Object> y);
955 884
956 885
957 // Factory method for getting an uninitialized compare stub. 886 // Factory method for getting an uninitialized compare stub.
958 static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op); 887 static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op);
959 888
960 // Helper function for computing the condition for a compare operation. 889 // Helper function for computing the condition for a compare operation.
961 static Condition ComputeCondition(Token::Value op); 890 static Condition ComputeCondition(Token::Value op);
962 891
963 static const char* GetStateName(State state); 892 static const char* GetStateName(State state);
964 893
965 private: 894 private:
966 static bool HasInlinedSmiCode(Address address); 895 static bool HasInlinedSmiCode(Address address);
967 896
968 State TargetState(State old_state, 897 State TargetState(State old_state, State old_left, State old_right,
969 State old_left, 898 bool has_inlined_smi_code, Handle<Object> x,
970 State old_right,
971 bool has_inlined_smi_code,
972 Handle<Object> x,
973 Handle<Object> y); 899 Handle<Object> y);
974 900
975 bool strict() const { return op_ == Token::EQ_STRICT; } 901 bool strict() const { return op_ == Token::EQ_STRICT; }
976 Condition GetCondition() const { return ComputeCondition(op_); } 902 Condition GetCondition() const { return ComputeCondition(op_); }
977 903
978 static Code* GetRawUninitialized(Isolate* isolate, Token::Value op); 904 static Code* GetRawUninitialized(Isolate* isolate, Token::Value op);
979 905
980 static void Clear(Isolate* isolate, 906 static void Clear(Isolate* isolate, Address address, Code* target,
981 Address address,
982 Code* target,
983 ConstantPoolArray* constant_pool); 907 ConstantPoolArray* constant_pool);
984 908
985 Token::Value op_; 909 Token::Value op_;
986 910
987 friend class IC; 911 friend class IC;
988 }; 912 };
989 913
990 914
991 class CompareNilIC: public IC { 915 class CompareNilIC : public IC {
992 public: 916 public:
993 explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} 917 explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
994 918
995 Handle<Object> CompareNil(Handle<Object> object); 919 Handle<Object> CompareNil(Handle<Object> object);
996 920
997 static Handle<Code> GetUninitialized(); 921 static Handle<Code> GetUninitialized();
998 922
999 static void Clear(Address address, 923 static void Clear(Address address, Code* target,
1000 Code* target,
1001 ConstantPoolArray* constant_pool); 924 ConstantPoolArray* constant_pool);
1002 925
1003 static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil, 926 static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil,
1004 Handle<Object> object); 927 Handle<Object> object);
1005 }; 928 };
1006 929
1007 930
1008 class ToBooleanIC: public IC { 931 class ToBooleanIC : public IC {
1009 public: 932 public:
1010 explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } 933 explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
1011 934
1012 Handle<Object> ToBoolean(Handle<Object> object); 935 Handle<Object> ToBoolean(Handle<Object> object);
1013 }; 936 };
1014 937
1015 938
1016 // Helper for BinaryOpIC and CompareIC. 939 // Helper for BinaryOpIC and CompareIC.
1017 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; 940 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
1018 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check); 941 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
1019 942
1020 DECLARE_RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure); 943 DECLARE_RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure);
1021 DECLARE_RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure); 944 DECLARE_RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure);
1022 DECLARE_RUNTIME_FUNCTION(UnaryOpIC_Miss); 945 DECLARE_RUNTIME_FUNCTION(UnaryOpIC_Miss);
1023 DECLARE_RUNTIME_FUNCTION(StoreIC_MissFromStubFailure); 946 DECLARE_RUNTIME_FUNCTION(StoreIC_MissFromStubFailure);
1024 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); 947 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss);
1025 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); 948 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss);
1026 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); 949 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite);
1027 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); 950 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss);
1028 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); 951 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss);
1029 952
953 // Support functions for callbacks handlers.
954 DECLARE_RUNTIME_FUNCTION(StoreCallbackProperty);
1030 955
1031 } } // namespace v8::internal 956 // Support functions for interceptor handlers.
957 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly);
958 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor);
959 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor);
960 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor);
961 }
962 } // namespace v8::internal
1032 963
1033 #endif // V8_IC_H_ 964 #endif // V8_IC_H_
OLDNEW
« no previous file with comments | « src/ic/ia32/stub-cache-ia32.cc ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698