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

Side by Side Diff: src/ic.h

Issue 157543002: A64: Synchronize with r18581. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/ia32/stub-cache-ia32.cc ('k') | src/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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 // Alias the inline cache state type to make the IC code more readable. 82 // Alias the inline cache state type to make the IC code more readable.
83 typedef InlineCacheState State; 83 typedef InlineCacheState State;
84 84
85 // The IC code is either invoked with no extra frames on the stack 85 // The IC code is either invoked with no extra frames on the stack
86 // or with a single extra frame for supporting calls. 86 // or with a single extra frame for supporting calls.
87 enum FrameDepth { 87 enum FrameDepth {
88 NO_EXTRA_FRAME = 0, 88 NO_EXTRA_FRAME = 0,
89 EXTRA_CALL_FRAME = 1 89 EXTRA_CALL_FRAME = 1
90 }; 90 };
91 91
92 // ExtraICState shared by all ICs.
93 class Contextual: public BitField<ContextualMode, 0, 1> {};
94 STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
95 static ExtraICState ComputeExtraICState(ContextualMode mode) {
96 return Contextual::encode(mode);
97 }
98
99 static ContextualMode GetContextualMode(ExtraICState state) {
100 return Contextual::decode(state);
101 }
102
103 static const ExtraICState kContextualState =
104 static_cast<int>(CONTEXTUAL) << Contextual::kShift;
105
92 // Construct the IC structure with the given number of extra 106 // Construct the IC structure with the given number of extra
93 // JavaScript frames on the stack. 107 // JavaScript frames on the stack.
94 IC(FrameDepth depth, Isolate* isolate); 108 IC(FrameDepth depth, Isolate* isolate);
95 virtual ~IC() {} 109 virtual ~IC() {}
96 110
97 State state() const { return state_; } 111 State state() const { return state_; }
98 inline Address address() const; 112 inline Address address() const;
99 113
100 // Compute the current IC state based on the target stub, receiver and name. 114 // Compute the current IC state based on the target stub, receiver and name.
101 void UpdateState(Handle<Object> receiver, Handle<Object> name); 115 void UpdateState(Handle<Object> receiver, Handle<Object> name);
102 void MarkMonomorphicPrototypeFailure() { 116 void MarkMonomorphicPrototypeFailure() {
103 state_ = MONOMORPHIC_PROTOTYPE_FAILURE; 117 state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
104 } 118 }
105 119
106 // Clear the inline cache to initial state. 120 // Clear the inline cache to initial state.
107 static void Clear(Isolate* isolate, Address address); 121 static void Clear(Isolate* isolate, Address address);
108 122
109 // Computes the reloc info for this IC. This is a fairly expensive
110 // operation as it has to search through the heap to find the code
111 // object that contains this IC site.
112 RelocInfo::Mode ComputeMode();
113
114 // Returns if this IC is for contextual (no explicit receiver) 123 // Returns if this IC is for contextual (no explicit receiver)
115 // access to properties. 124 // access to properties.
116 bool IsUndeclaredGlobal(Handle<Object> receiver) { 125 bool IsUndeclaredGlobal(Handle<Object> receiver) {
117 if (receiver->IsGlobalObject()) { 126 if (receiver->IsGlobalObject()) {
118 return SlowIsUndeclaredGlobal(); 127 return IsContextual();
119 } else { 128 } else {
120 ASSERT(!SlowIsUndeclaredGlobal()); 129 ASSERT(!IsContextual());
121 return false; 130 return false;
122 } 131 }
123 } 132 }
124 133
125 bool SlowIsUndeclaredGlobal() {
126 return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
127 }
128
129 #ifdef DEBUG 134 #ifdef DEBUG
130 bool IsLoadStub() { 135 bool IsLoadStub() {
131 return target()->is_load_stub() || target()->is_keyed_load_stub(); 136 return target()->is_load_stub() || target()->is_keyed_load_stub();
132 } 137 }
133 138
134 bool IsStoreStub() { 139 bool IsStoreStub() {
135 return target()->is_store_stub() || target()->is_keyed_store_stub(); 140 return target()->is_store_stub() || target()->is_keyed_store_stub();
136 } 141 }
137 142
138 bool IsCallStub() { 143 bool IsCallStub() {
(...skipping 20 matching lines...) Expand all
159 InlineCacheState state = code->ic_state(); 164 InlineCacheState state = code->ic_state();
160 return state == UNINITIALIZED || state == PREMONOMORPHIC; 165 return state == UNINITIALIZED || state == PREMONOMORPHIC;
161 } 166 }
162 167
163 // Utility functions to convert maps to types and back. There are two special 168 // Utility functions to convert maps to types and back. There are two special
164 // cases: 169 // cases:
165 // - The heap_number_map is used as a marker which includes heap numbers as 170 // - The heap_number_map is used as a marker which includes heap numbers as
166 // well as smis. 171 // well as smis.
167 // - The oddball map is only used for booleans. 172 // - The oddball map is only used for booleans.
168 static Handle<Map> TypeToMap(Type* type, Isolate* isolate); 173 static Handle<Map> TypeToMap(Type* type, Isolate* isolate);
169 static Type* MapToType(Handle<Map> type); 174 static Handle<Type> MapToType(Handle<Map> type);
170 static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate); 175 static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate);
171 176
177 ContextualMode contextual_mode() const {
178 return Contextual::decode(extra_ic_state());
179 }
180
181 bool IsContextual() const { return contextual_mode() == CONTEXTUAL; }
182
172 protected: 183 protected:
173 // Get the call-site target; used for determining the state. 184 // Get the call-site target; used for determining the state.
174 Handle<Code> target() const { return target_; } 185 Handle<Code> target() const { return target_; }
175 186
176 Address fp() const { return fp_; } 187 Address fp() const { return fp_; }
177 Address pc() const { return *pc_address_; } 188 Address pc() const { return *pc_address_; }
178 Isolate* isolate() const { return isolate_; } 189 Isolate* isolate() const { return isolate_; }
179 190
180 #ifdef ENABLE_DEBUGGER_SUPPORT 191 #ifdef ENABLE_DEBUGGER_SUPPORT
181 // Computes the address in the original code when the code running is 192 // Computes the address in the original code when the code running is
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 Handle<Code> handler, 236 Handle<Code> handler,
226 Handle<String> name); 237 Handle<String> name);
227 238
228 bool UpdatePolymorphicIC(Handle<Type> type, 239 bool UpdatePolymorphicIC(Handle<Type> type,
229 Handle<String> name, 240 Handle<String> name,
230 Handle<Code> code); 241 Handle<Code> code);
231 242
232 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code); 243 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code);
233 244
234 void CopyICToMegamorphicCache(Handle<String> name); 245 void CopyICToMegamorphicCache(Handle<String> name);
235 bool IsTransitionOfMonomorphicTarget(Type* type); 246 bool IsTransitionOfMonomorphicTarget(Handle<Type> type);
236 void PatchCache(Handle<Type> type, 247 void PatchCache(Handle<Type> type,
237 Handle<String> name, 248 Handle<String> name,
238 Handle<Code> code); 249 Handle<Code> code);
239 virtual Code::Kind kind() const { 250 virtual Code::Kind kind() const {
240 UNREACHABLE(); 251 UNREACHABLE();
241 return Code::STUB; 252 return Code::STUB;
242 } 253 }
243 virtual Handle<Code> slow_stub() const { 254 virtual Handle<Code> slow_stub() const {
244 UNREACHABLE(); 255 UNREACHABLE();
245 return Handle<Code>::null(); 256 return Handle<Code>::null();
246 } 257 }
247 virtual Handle<Code> megamorphic_stub() { 258 virtual Handle<Code> megamorphic_stub() {
248 UNREACHABLE(); 259 UNREACHABLE();
249 return Handle<Code>::null(); 260 return Handle<Code>::null();
250 } 261 }
251 virtual Handle<Code> generic_stub() const { 262 virtual Handle<Code> generic_stub() const {
252 UNREACHABLE(); 263 UNREACHABLE();
253 return Handle<Code>::null(); 264 return Handle<Code>::null();
254 } 265 }
255 266
256 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 267 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
257 Handle<String> name); 268 Handle<String> name);
258 void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name); 269 void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
259 270
260 virtual ExtraICState extra_ic_state() { return kNoExtraICState; } 271 ExtraICState extra_ic_state() const { return extra_ic_state_; }
272 void set_extra_ic_state(ExtraICState state) {
273 extra_ic_state_ = state;
274 }
261 275
262 private: 276 private:
263 Code* raw_target() const { return GetTargetAtAddress(address()); } 277 Code* raw_target() const { return GetTargetAtAddress(address()); }
264 278
265 // Frame pointer for the frame that uses (calls) the IC. 279 // Frame pointer for the frame that uses (calls) the IC.
266 Address fp_; 280 Address fp_;
267 281
268 // All access to the program counter of an IC structure is indirect 282 // All access to the program counter of an IC structure is indirect
269 // to make the code GC safe. This feature is crucial since 283 // to make the code GC safe. This feature is crucial since
270 // GetProperty and SetProperty are called and they in turn might 284 // GetProperty and SetProperty are called and they in turn might
271 // invoke the garbage collector. 285 // invoke the garbage collector.
272 Address* pc_address_; 286 Address* pc_address_;
273 287
274 Isolate* isolate_; 288 Isolate* isolate_;
275 289
276 // The original code target that missed. 290 // The original code target that missed.
277 Handle<Code> target_; 291 Handle<Code> target_;
278 State state_; 292 State state_;
279 bool target_set_; 293 bool target_set_;
280 294
295 ExtraICState extra_ic_state_;
296
281 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); 297 DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
282 }; 298 };
283 299
284 300
285 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you 301 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you
286 // cannot make forward declarations to an enum. 302 // cannot make forward declarations to an enum.
287 class IC_Utility { 303 class IC_Utility {
288 public: 304 public:
289 explicit IC_Utility(IC::UtilityId id) 305 explicit IC_Utility(IC::UtilityId id)
290 : address_(IC::AddressFromUtilityId(id)), id_(id) {} 306 : address_(IC::AddressFromUtilityId(id)), id_(id) {}
291 307
292 Address address() const { return address_; } 308 Address address() const { return address_; }
293 309
294 IC::UtilityId id() const { return id_; } 310 IC::UtilityId id() const { return id_; }
295 private: 311 private:
296 Address address_; 312 Address address_;
297 IC::UtilityId id_; 313 IC::UtilityId id_;
298 }; 314 };
299 315
300 316
301 enum StringStubFeedback { 317 enum StringStubFeedback {
302 DEFAULT_STRING_STUB = 0, 318 DEFAULT_STRING_STUB = 0,
303 STRING_INDEX_OUT_OF_BOUNDS = 1 319 STRING_INDEX_OUT_OF_BOUNDS = 1
304 }; 320 };
305 321
306 322
307 class CallICBase: public IC { 323 class CallICBase: public IC {
308 public: 324 public:
309 // ExtraICState bits 325 // ExtraICState bits
310 class Contextual: public BitField<ContextualMode, 0, 1> {};
311 class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; 326 class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
312 static ExtraICState ComputeExtraICState(ContextualMode mode, 327 static ExtraICState ComputeExtraICState(ContextualMode mode,
313 StringStubFeedback feedback) { 328 StringStubFeedback feedback) {
314 return Contextual::encode(mode) | StringStubState::encode(feedback); 329 return Contextual::encode(mode) | StringStubState::encode(feedback);
315 } 330 }
316 331
317 // Returns a JSFunction or a Failure. 332 // Returns a JSFunction or a Failure.
318 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, 333 MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
319 Handle<String> name); 334 Handle<String> name);
320 335
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 376
362 Code::Kind kind_; 377 Code::Kind kind_;
363 378
364 friend class IC; 379 friend class IC;
365 }; 380 };
366 381
367 382
368 class CallIC: public CallICBase { 383 class CallIC: public CallICBase {
369 public: 384 public:
370 explicit CallIC(Isolate* isolate) 385 explicit CallIC(Isolate* isolate)
371 : CallICBase(Code::CALL_IC, isolate), 386 : CallICBase(Code::CALL_IC, isolate) {
372 extra_ic_state_(target()->extra_ic_state()) {
373 ASSERT(target()->is_call_stub()); 387 ASSERT(target()->is_call_stub());
374 } 388 }
375 389
376 // Code generator routines. 390 // Code generator routines.
377 static void GenerateInitialize(MacroAssembler* masm, 391 static void GenerateInitialize(MacroAssembler* masm,
378 int argc, 392 int argc,
379 ExtraICState extra_state) { 393 ExtraICState extra_state) {
380 GenerateMiss(masm, argc, extra_state); 394 GenerateMiss(masm, argc, extra_state);
381 } 395 }
382 396
383 static void GenerateMiss(MacroAssembler* masm, 397 static void GenerateMiss(MacroAssembler* masm,
384 int argc, 398 int argc,
385 ExtraICState extra_state) { 399 ExtraICState extra_state) {
386 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state); 400 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state);
387 } 401 }
388 402
389 static void GenerateMegamorphic(MacroAssembler* masm, 403 static void GenerateMegamorphic(MacroAssembler* masm,
390 int argc, 404 int argc,
391 ExtraICState extra_ic_state); 405 ExtraICState extra_ic_state);
392 406
393 static void GenerateNormal(MacroAssembler* masm, int argc) { 407 static void GenerateNormal(MacroAssembler* masm, int argc) {
394 CallICBase::GenerateNormal(masm, argc); 408 CallICBase::GenerateNormal(masm, argc);
395 GenerateMiss(masm, argc, kNoExtraICState); 409 GenerateMiss(masm, argc, kNoExtraICState);
396 } 410 }
397 bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object); 411 bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object);
398
399 protected:
400 virtual ExtraICState extra_ic_state() { return extra_ic_state_; }
401
402 private:
403 ExtraICState extra_ic_state_;
404 }; 412 };
405 413
406 414
407 class KeyedCallIC: public CallICBase { 415 class KeyedCallIC: public CallICBase {
408 public: 416 public:
409 explicit KeyedCallIC(Isolate* isolate) 417 explicit KeyedCallIC(Isolate* isolate)
410 : CallICBase(Code::KEYED_CALL_IC, isolate) { 418 : CallICBase(Code::KEYED_CALL_IC, isolate) {
411 ASSERT(target()->is_keyed_call_stub()); 419 ASSERT(target()->is_keyed_call_stub());
412 } 420 }
413 421
(...skipping 11 matching lines...) Expand all
425 } 433 }
426 434
427 static void GenerateMegamorphic(MacroAssembler* masm, int argc); 435 static void GenerateMegamorphic(MacroAssembler* masm, int argc);
428 static void GenerateNormal(MacroAssembler* masm, int argc); 436 static void GenerateNormal(MacroAssembler* masm, int argc);
429 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); 437 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
430 }; 438 };
431 439
432 440
433 class LoadIC: public IC { 441 class LoadIC: public IC {
434 public: 442 public:
435 explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) { 443 explicit LoadIC(FrameDepth depth, Isolate* isolate)
444 : IC(depth, isolate) {
436 ASSERT(IsLoadStub()); 445 ASSERT(IsLoadStub());
437 } 446 }
438 447
439 // Code generator routines. 448 // Code generator routines.
440 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 449 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
441 static void GeneratePreMonomorphic(MacroAssembler* masm) { 450 static void GeneratePreMonomorphic(MacroAssembler* masm) {
442 GenerateMiss(masm); 451 GenerateMiss(masm);
443 } 452 }
444 static void GenerateMiss(MacroAssembler* masm); 453 static void GenerateMiss(MacroAssembler* masm);
445 static void GenerateMegamorphic(MacroAssembler* masm); 454 static void GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode);
446 static void GenerateNormal(MacroAssembler* masm); 455 static void GenerateNormal(MacroAssembler* masm);
447 static void GenerateRuntimeGetProperty(MacroAssembler* masm); 456 static void GenerateRuntimeGetProperty(MacroAssembler* masm);
448 457
458 static Handle<Code> initialize_stub(Isolate* isolate, ContextualMode mode);
459
449 MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, 460 MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
450 Handle<String> name); 461 Handle<String> name);
451 462
452 protected: 463 protected:
453 virtual Code::Kind kind() const { return Code::LOAD_IC; } 464 virtual Code::Kind kind() const { return Code::LOAD_IC; }
454 465
455 virtual Handle<Code> slow_stub() const { 466 virtual Handle<Code> slow_stub() const {
456 return isolate()->builtins()->LoadIC_Slow(); 467 return isolate()->builtins()->LoadIC_Slow();
457 } 468 }
458 469
459 virtual Handle<Code> megamorphic_stub() { 470 virtual Handle<Code> megamorphic_stub();
460 return isolate()->builtins()->LoadIC_Megamorphic();
461 }
462 471
463 // Update the inline cache and the global stub cache based on the 472 // Update the inline cache and the global stub cache based on the
464 // lookup result. 473 // lookup result.
465 void UpdateCaches(LookupResult* lookup, 474 void UpdateCaches(LookupResult* lookup,
466 Handle<Object> object, 475 Handle<Object> object,
467 Handle<String> name); 476 Handle<String> name);
468 477
469 virtual Handle<Code> CompileHandler(LookupResult* lookup, 478 virtual Handle<Code> CompileHandler(LookupResult* lookup,
470 Handle<Object> object, 479 Handle<Object> object,
471 Handle<String> name, 480 Handle<String> name,
472 Handle<Object> unused, 481 Handle<Object> unused,
473 InlineCacheHolderFlag cache_holder); 482 InlineCacheHolderFlag cache_holder);
474 483
475 private: 484 private:
476 // Stub accessors. 485 // Stub accessors.
477 static Handle<Code> initialize_stub(Isolate* isolate) { 486 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
478 return isolate->builtins()->LoadIC_Initialize(); 487 ContextualMode mode);
479 }
480
481 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
482 return isolate->builtins()->LoadIC_PreMonomorphic();
483 }
484 488
485 virtual Handle<Code> pre_monomorphic_stub() { 489 virtual Handle<Code> pre_monomorphic_stub() {
486 return pre_monomorphic_stub(isolate()); 490 return pre_monomorphic_stub(isolate(), contextual_mode());
487 } 491 }
488 492
489 Handle<Code> SimpleFieldLoad(int offset, 493 Handle<Code> SimpleFieldLoad(int offset,
490 bool inobject = true, 494 bool inobject = true,
491 Representation representation = 495 Representation representation =
492 Representation::Tagged()); 496 Representation::Tagged());
493 497
494 static void Clear(Isolate* isolate, Address address, Code* target); 498 static void Clear(Isolate* isolate, Address address, Code* target);
495 499
496 friend class IC; 500 friend class IC;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 return isolate()->builtins()->KeyedLoadIC_Generic(); 542 return isolate()->builtins()->KeyedLoadIC_Generic();
539 } 543 }
540 virtual Handle<Code> slow_stub() const { 544 virtual Handle<Code> slow_stub() const {
541 return isolate()->builtins()->KeyedLoadIC_Slow(); 545 return isolate()->builtins()->KeyedLoadIC_Slow();
542 } 546 }
543 547
544 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } 548 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
545 549
546 private: 550 private:
547 // Stub accessors. 551 // Stub accessors.
548 static Handle<Code> initialize_stub(Isolate* isolate) {
549 return isolate->builtins()->KeyedLoadIC_Initialize();
550 }
551 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { 552 static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
552 return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); 553 return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
553 } 554 }
554 virtual Handle<Code> pre_monomorphic_stub() { 555 virtual Handle<Code> pre_monomorphic_stub() {
555 return pre_monomorphic_stub(isolate()); 556 return pre_monomorphic_stub(isolate());
556 } 557 }
557 Handle<Code> indexed_interceptor_stub() { 558 Handle<Code> indexed_interceptor_stub() {
558 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor(); 559 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
559 } 560 }
560 Handle<Code> non_strict_arguments_stub() { 561 Handle<Code> non_strict_arguments_stub() {
561 return isolate()->builtins()->KeyedLoadIC_NonStrictArguments(); 562 return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
562 } 563 }
563 Handle<Code> string_stub() { 564 Handle<Code> string_stub() {
564 return isolate()->builtins()->KeyedLoadIC_String(); 565 return isolate()->builtins()->KeyedLoadIC_String();
565 } 566 }
566 567
567 static void Clear(Isolate* isolate, Address address, Code* target); 568 static void Clear(Isolate* isolate, Address address, Code* target);
568 569
569 friend class IC; 570 friend class IC;
570 }; 571 };
571 572
572 573
573 class StoreIC: public IC { 574 class StoreIC: public IC {
574 public: 575 public:
575 // ExtraICState bits 576 // ExtraICState bits
576 class StrictModeState: public BitField<StrictModeFlag, 0, 1> {}; 577 class StrictModeState: public BitField<StrictModeFlag, 1, 1> {};
577 static ExtraICState ComputeExtraICState(StrictModeFlag flag) { 578 static ExtraICState ComputeExtraICState(StrictModeFlag flag) {
578 return StrictModeState::encode(flag); 579 return StrictModeState::encode(flag);
579 } 580 }
580 581
582 static ExtraICState ComputeExtraICState(StrictModeFlag flag,
583 ContextualMode mode) {
584 return StrictModeState::encode(flag) | Contextual::encode(mode);
585 }
586
581 static StrictModeFlag GetStrictMode(ExtraICState state) { 587 static StrictModeFlag GetStrictMode(ExtraICState state) {
582 return StrictModeState::decode(state); 588 return StrictModeState::decode(state);
583 } 589 }
584 590
585 // For convenience, a statically declared encoding of strict mode extra 591 // For convenience, a statically declared encoding of strict mode extra
586 // IC state. 592 // IC state.
587 static const ExtraICState kStrictModeState = 593 static const ExtraICState kStrictModeState =
588 1 << StrictModeState::kShift; 594 1 << StrictModeState::kShift;
589 595
590 StoreIC(FrameDepth depth, Isolate* isolate) 596 StoreIC(FrameDepth depth, Isolate* isolate)
591 : IC(depth, isolate), 597 : IC(depth, isolate) {
592 strict_mode_(GetStrictMode(target()->extra_ic_state())) {
593 ASSERT(IsStoreStub()); 598 ASSERT(IsStoreStub());
594 } 599 }
595 600
596 StrictModeFlag strict_mode() const { return strict_mode_; } 601 StrictModeFlag strict_mode() const {
602 return StrictModeState::decode(extra_ic_state());
603 }
597 604
598 // Code generators for stub routines. Only called once at startup. 605 // Code generators for stub routines. Only called once at startup.
599 static void GenerateSlow(MacroAssembler* masm); 606 static void GenerateSlow(MacroAssembler* masm);
600 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 607 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
601 static void GeneratePreMonomorphic(MacroAssembler* masm) { 608 static void GeneratePreMonomorphic(MacroAssembler* masm) {
602 GenerateMiss(masm); 609 GenerateMiss(masm);
603 } 610 }
604 static void GenerateMiss(MacroAssembler* masm); 611 static void GenerateMiss(MacroAssembler* masm);
605 static void GenerateMegamorphic(MacroAssembler* masm, 612 static void GenerateMegamorphic(MacroAssembler* masm,
606 ExtraICState extra_ic_state); 613 ExtraICState extra_ic_state);
607 static void GenerateNormal(MacroAssembler* masm); 614 static void GenerateNormal(MacroAssembler* masm);
608 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 615 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
609 StrictModeFlag strict_mode); 616 StrictModeFlag strict_mode);
610 617
618 static Handle<Code> initialize_stub(Isolate* isolate,
619 StrictModeFlag strict_mode,
620 ContextualMode mode);
621
611 MUST_USE_RESULT MaybeObject* Store( 622 MUST_USE_RESULT MaybeObject* Store(
612 Handle<Object> object, 623 Handle<Object> object,
613 Handle<String> name, 624 Handle<String> name,
614 Handle<Object> value, 625 Handle<Object> value,
615 JSReceiver::StoreFromKeyed store_mode = 626 JSReceiver::StoreFromKeyed store_mode =
616 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); 627 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
617 628
618 protected: 629 protected:
619 virtual Code::Kind kind() const { return Code::STORE_IC; } 630 virtual Code::Kind kind() const { return Code::STORE_IC; }
620 virtual Handle<Code> megamorphic_stub() { 631 virtual Handle<Code> megamorphic_stub();
621 if (strict_mode() == kStrictMode) { 632
622 return isolate()->builtins()->StoreIC_Megamorphic_Strict();
623 } else {
624 return isolate()->builtins()->StoreIC_Megamorphic();
625 }
626 }
627 // Stub accessors. 633 // Stub accessors.
628 virtual Handle<Code> generic_stub() const { 634 virtual Handle<Code> generic_stub() const;
629 if (strict_mode() == kStrictMode) {
630 return isolate()->builtins()->StoreIC_Generic_Strict();
631 } else {
632 return isolate()->builtins()->StoreIC_Generic();
633 }
634 }
635 635
636 virtual Handle<Code> slow_stub() const { 636 virtual Handle<Code> slow_stub() const {
637 return isolate()->builtins()->StoreIC_Slow(); 637 return isolate()->builtins()->StoreIC_Slow();
638 } 638 }
639 639
640 virtual Handle<Code> pre_monomorphic_stub() { 640 virtual Handle<Code> pre_monomorphic_stub() {
641 return pre_monomorphic_stub(isolate(), strict_mode()); 641 return pre_monomorphic_stub(isolate(), strict_mode(), contextual_mode());
642 } 642 }
643 643
644 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, 644 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
645 StrictModeFlag strict_mode) { 645 StrictModeFlag strict_mode,
646 if (strict_mode == kStrictMode) { 646 ContextualMode contextual_mode);
647 return isolate->builtins()->StoreIC_PreMonomorphic_Strict();
648 } else {
649 return isolate->builtins()->StoreIC_PreMonomorphic();
650 }
651 }
652 647
653 // Update the inline cache and the global stub cache based on the 648 // Update the inline cache and the global stub cache based on the
654 // lookup result. 649 // lookup result.
655 void UpdateCaches(LookupResult* lookup, 650 void UpdateCaches(LookupResult* lookup,
656 Handle<JSObject> receiver, 651 Handle<JSObject> receiver,
657 Handle<String> name, 652 Handle<String> name,
658 Handle<Object> value); 653 Handle<Object> value);
659 virtual Handle<Code> CompileHandler(LookupResult* lookup, 654 virtual Handle<Code> CompileHandler(LookupResult* lookup,
660 Handle<Object> object, 655 Handle<Object> object,
661 Handle<String> name, 656 Handle<String> name,
662 Handle<Object> value, 657 Handle<Object> value,
663 InlineCacheHolderFlag cache_holder); 658 InlineCacheHolderFlag cache_holder);
664 659
665 virtual ExtraICState extra_ic_state() {
666 return ComputeExtraICState(strict_mode());
667 }
668
669 private: 660 private:
670 void set_target(Code* code) { 661 void set_target(Code* code) {
671 // Strict mode must be preserved across IC patching. 662 // Strict mode must be preserved across IC patching.
672 ASSERT(GetStrictMode(code->extra_ic_state()) == 663 ASSERT(GetStrictMode(code->extra_ic_state()) ==
673 GetStrictMode(target()->extra_ic_state())); 664 GetStrictMode(target()->extra_ic_state()));
665 // As must the contextual mode
666 ASSERT(GetContextualMode(code->extra_ic_state()) ==
667 GetContextualMode(target()->extra_ic_state()));
674 IC::set_target(code); 668 IC::set_target(code);
675 } 669 }
676 670
677 static Handle<Code> initialize_stub(Isolate* isolate,
678 StrictModeFlag strict_mode) {
679 if (strict_mode == kStrictMode) {
680 return isolate->builtins()->StoreIC_Initialize_Strict();
681 } else {
682 return isolate->builtins()->StoreIC_Initialize();
683 }
684 }
685
686 static void Clear(Isolate* isolate, Address address, Code* target); 671 static void Clear(Isolate* isolate, Address address, Code* target);
687 672
688 StrictModeFlag strict_mode_;
689
690 friend class IC; 673 friend class IC;
691 }; 674 };
692 675
693 676
694 enum KeyedStoreCheckMap { 677 enum KeyedStoreCheckMap {
695 kDontCheckMap, 678 kDontCheckMap,
696 kCheckMap 679 kCheckMap
697 }; 680 };
698 681
699 682
700 enum KeyedStoreIncrementLength { 683 enum KeyedStoreIncrementLength {
701 kDontIncrementLength, 684 kDontIncrementLength,
702 kIncrementLength 685 kIncrementLength
703 }; 686 };
704 687
705 688
706 class KeyedStoreIC: public StoreIC { 689 class KeyedStoreIC: public StoreIC {
707 public: 690 public:
708 // ExtraICState bits (building on IC) 691 // ExtraICState bits (building on IC)
709 // ExtraICState bits 692 // ExtraICState bits
710 class ExtraICStateKeyedAccessStoreMode: 693 class ExtraICStateKeyedAccessStoreMode:
711 public BitField<KeyedAccessStoreMode, 1, 4> {}; // NOLINT 694 public BitField<KeyedAccessStoreMode, 2, 4> {}; // NOLINT
712 695
713 static ExtraICState ComputeExtraICState(StrictModeFlag flag, 696 static ExtraICState ComputeExtraICState(StrictModeFlag flag,
714 KeyedAccessStoreMode mode) { 697 KeyedAccessStoreMode mode) {
715 return StrictModeState::encode(flag) | 698 return StrictModeState::encode(flag) |
716 ExtraICStateKeyedAccessStoreMode::encode(mode); 699 ExtraICStateKeyedAccessStoreMode::encode(mode);
717 } 700 }
718 701
719 static KeyedAccessStoreMode GetKeyedAccessStoreMode( 702 static KeyedAccessStoreMode GetKeyedAccessStoreMode(
720 ExtraICState extra_state) { 703 ExtraICState extra_state) {
721 return ExtraICStateKeyedAccessStoreMode::decode(extra_state); 704 return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
722 } 705 }
723 706
724 KeyedStoreIC(FrameDepth depth, Isolate* isolate) 707 KeyedStoreIC(FrameDepth depth, Isolate* isolate)
(...skipping 15 matching lines...) Expand all
740 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 723 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
741 StrictModeFlag strict_mode); 724 StrictModeFlag strict_mode);
742 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); 725 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
743 static void GenerateNonStrictArguments(MacroAssembler* masm); 726 static void GenerateNonStrictArguments(MacroAssembler* masm);
744 727
745 protected: 728 protected:
746 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } 729 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
747 730
748 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } 731 virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
749 732
750 virtual ExtraICState extra_ic_state() {
751 return ComputeExtraICState(strict_mode(), STANDARD_STORE);
752 }
753
754 virtual Handle<Code> pre_monomorphic_stub() { 733 virtual Handle<Code> pre_monomorphic_stub() {
755 return pre_monomorphic_stub(isolate(), strict_mode()); 734 return pre_monomorphic_stub(isolate(), strict_mode());
756 } 735 }
757 static Handle<Code> pre_monomorphic_stub(Isolate* isolate, 736 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
758 StrictModeFlag strict_mode) { 737 StrictModeFlag strict_mode) {
759 if (strict_mode == kStrictMode) { 738 if (strict_mode == kStrictMode) {
760 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); 739 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
761 } else { 740 } else {
762 return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); 741 return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
763 } 742 }
(...skipping 13 matching lines...) Expand all
777 KeyedAccessStoreMode store_mode); 756 KeyedAccessStoreMode store_mode);
778 757
779 private: 758 private:
780 void set_target(Code* code) { 759 void set_target(Code* code) {
781 // Strict mode must be preserved across IC patching. 760 // Strict mode must be preserved across IC patching.
782 ASSERT(GetStrictMode(code->extra_ic_state()) == strict_mode()); 761 ASSERT(GetStrictMode(code->extra_ic_state()) == strict_mode());
783 IC::set_target(code); 762 IC::set_target(code);
784 } 763 }
785 764
786 // Stub accessors. 765 // Stub accessors.
787 static Handle<Code> initialize_stub(Isolate* isolate,
788 StrictModeFlag strict_mode) {
789 if (strict_mode == kStrictMode) {
790 return isolate->builtins()->KeyedStoreIC_Initialize_Strict();
791 } else {
792 return isolate->builtins()->KeyedStoreIC_Initialize();
793 }
794 }
795
796 virtual Handle<Code> generic_stub() const { 766 virtual Handle<Code> generic_stub() const {
797 if (strict_mode() == kStrictMode) { 767 if (strict_mode() == kStrictMode) {
798 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 768 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
799 } else { 769 } else {
800 return isolate()->builtins()->KeyedStoreIC_Generic(); 770 return isolate()->builtins()->KeyedStoreIC_Generic();
801 } 771 }
802 } 772 }
803 773
804 Handle<Code> non_strict_arguments_stub() { 774 Handle<Code> non_strict_arguments_stub() {
805 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); 775 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); 1025 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
1056 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); 1026 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss);
1057 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite); 1027 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite);
1058 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); 1028 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
1059 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); 1029 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
1060 1030
1061 1031
1062 } } // namespace v8::internal 1032 } } // namespace v8::internal
1063 1033
1064 #endif // V8_IC_H_ 1034 #endif // V8_IC_H_
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698