198
204
class Contextual: public BitField<bool, 0, 1> {};
199
205
class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
207
// Returns a JSFunction or a Failure.
208
MUST_USE_RESULT MaybeObject* LoadFunction(State state,
209
Code::ExtraICState extra_ic_state,
210
Handle<Object> object,
211
Handle<String> name);
202
214
CallICBase(Code::Kind kind, Isolate* isolate)
203
215
: IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
206
MUST_USE_RESULT MaybeObject* LoadFunction(State state,
207
Code::ExtraICState extra_ic_state,
208
Handle<Object> object,
209
Handle<String> name);
214
217
bool TryUpdateExtraICState(LookupResult* lookup,
215
218
Handle<Object> object,
216
219
Code::ExtraICState* extra_ic_state);
218
MUST_USE_RESULT MaybeObject* ComputeMonomorphicStub(
219
LookupResult* lookup,
221
Code::ExtraICState extra_ic_state,
222
Handle<Object> object,
223
Handle<String> name);
221
// Compute a monomorphic stub if possible, otherwise return a null handle.
222
Handle<Code> ComputeMonomorphicStub(LookupResult* lookup,
224
Code::ExtraICState extra_state,
225
Handle<Object> object,
226
Handle<String> name);
225
// Update the inline cache and the global stub cache based on the
228
// Update the inline cache and the global stub cache based on the lookup
227
230
void UpdateCaches(LookupResult* lookup,
229
232
Code::ExtraICState extra_ic_state,
230
233
Handle<Object> object,
231
234
Handle<String> name);
233
// Returns a JSFunction if the object can be called as a function,
234
// and patches the stack to be ready for the call.
235
// Otherwise, it returns the undefined value.
236
Object* TryCallAsFunction(Object* object);
236
// Returns a JSFunction if the object can be called as a function, and
237
// patches the stack to be ready for the call. Otherwise, it returns the
239
Handle<Object> TryCallAsFunction(Handle<Object> object);
238
241
void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
240
243
static void Clear(Address address, Code* target);
245
// Platform-specific code generation functions used by both call and
247
static void GenerateMiss(MacroAssembler* masm,
250
Code::ExtraICState extra_state);
252
static void GenerateNormal(MacroAssembler* masm, int argc);
254
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
257
Code::ExtraICState extra_state);
252
271
// Code generator routines.
253
272
static void GenerateInitialize(MacroAssembler* masm,
255
Code::ExtraICState extra_ic_state) {
256
GenerateMiss(masm, argc, extra_ic_state);
274
Code::ExtraICState extra_state) {
275
GenerateMiss(masm, argc, extra_state);
258
278
static void GenerateMiss(MacroAssembler* masm,
260
Code::ExtraICState extra_ic_state);
280
Code::ExtraICState extra_state) {
281
CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state);
261
284
static void GenerateMegamorphic(MacroAssembler* masm,
263
286
Code::ExtraICState extra_ic_state);
264
static void GenerateNormal(MacroAssembler* masm, int argc);
288
static void GenerateNormal(MacroAssembler* masm, int argc) {
289
CallICBase::GenerateNormal(masm, argc);
290
GenerateMiss(masm, argc, Code::kNoExtraICState);
321
353
Handle<String> name);
323
355
// Stub accessors.
324
Code* megamorphic_stub() {
325
return isolate()->builtins()->builtin(
326
Builtins::kLoadIC_Megamorphic);
356
Handle<Code> megamorphic_stub() {
357
return isolate()->builtins()->LoadIC_Megamorphic();
328
359
static Code* initialize_stub() {
329
360
return Isolate::Current()->builtins()->builtin(
330
361
Builtins::kLoadIC_Initialize);
332
Code* pre_monomorphic_stub() {
333
return isolate()->builtins()->builtin(
334
Builtins::kLoadIC_PreMonomorphic);
363
Handle<Code> pre_monomorphic_stub() {
364
return isolate()->builtins()->LoadIC_PreMonomorphic();
337
367
static void Clear(Address address, Code* target);
343
373
class KeyedIC: public IC {
378
STORE_TRANSITION_SMI_TO_OBJECT,
379
STORE_TRANSITION_SMI_TO_DOUBLE,
380
STORE_TRANSITION_DOUBLE_TO_OBJECT,
381
STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
382
STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
383
STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
384
STORE_AND_GROW_NO_TRANSITION,
385
STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
386
STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
387
STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
388
STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
389
STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
390
STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT
393
static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
395
STATIC_ASSERT(kGrowICDelta ==
396
STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
397
STORE_TRANSITION_SMI_TO_OBJECT);
398
STATIC_ASSERT(kGrowICDelta ==
399
STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
400
STORE_TRANSITION_SMI_TO_DOUBLE);
401
STATIC_ASSERT(kGrowICDelta ==
402
STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
403
STORE_TRANSITION_DOUBLE_TO_OBJECT);
345
405
explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
346
406
virtual ~KeyedIC() {}
348
virtual MaybeObject* GetElementStubWithoutMapCheck(
408
static inline KeyedAccessGrowMode GetGrowModeFromStubKind(
409
StubKind stub_kind) {
410
return (stub_kind >= STORE_AND_GROW_NO_TRANSITION)
411
? ALLOW_JSARRAY_GROWTH
412
: DO_NOT_ALLOW_JSARRAY_GROWTH;
415
static inline StubKind GetGrowStubKind(StubKind stub_kind) {
416
ASSERT(stub_kind != LOAD);
417
if (stub_kind < STORE_AND_GROW_NO_TRANSITION) {
418
stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) +
424
virtual Handle<Code> GetElementStubWithoutMapCheck(
349
425
bool is_js_array,
350
ElementsKind elements_kind) = 0;
426
ElementsKind elements_kind,
427
KeyedAccessGrowMode grow_mode) = 0;
353
virtual Code* string_stub() {
430
virtual Handle<Code> string_stub() {
431
return Handle<Code>::null();
357
434
virtual Code::Kind kind() const = 0;
359
MaybeObject* ComputeStub(JSObject* receiver,
436
Handle<Code> ComputeStub(Handle<JSObject> receiver,
361
438
StrictModeFlag strict_mode,
364
virtual MaybeObject* ConstructMegamorphicStub(
365
MapList* receiver_maps,
367
StrictModeFlag strict_mode) = 0;
439
Handle<Code> default_stub);
441
virtual Handle<Code> ComputePolymorphicStub(
442
MapHandleList* receiver_maps,
443
StrictModeFlag strict_mode,
444
KeyedAccessGrowMode grow_mode) = 0;
446
Handle<Code> ComputeMonomorphicStubWithoutMapCheck(
447
Handle<Map> receiver_map,
448
StrictModeFlag strict_mode,
449
KeyedAccessGrowMode grow_mode);
370
void GetReceiverMapsForStub(Code* stub, MapList* result);
372
MaybeObject* ComputeMonomorphicStubWithoutMapCheck(
374
StrictModeFlag strict_mode);
376
MaybeObject* ComputeMonomorphicStub(JSObject* receiver,
452
void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
454
Handle<Code> ComputeMonomorphicStub(Handle<Map> receiver_map,
378
456
StrictModeFlag strict_mode,
457
Handle<Code> default_stub);
459
Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
462
static bool IsTransitionStubKind(StubKind stub_kind) {
463
return stub_kind > STORE_NO_TRANSITION &&
464
stub_kind != STORE_AND_GROW_NO_TRANSITION;
467
static bool IsGrowStubKind(StubKind stub_kind) {
468
return stub_kind >= STORE_AND_GROW_NO_TRANSITION;
471
static StubKind GetNoTransitionStubKind(StubKind stub_kind) {
472
if (!IsTransitionStubKind(stub_kind)) return stub_kind;
473
if (IsGrowStubKind(stub_kind)) return STORE_AND_GROW_NO_TRANSITION;
474
return STORE_NO_TRANSITION;
412
508
static const int kSlowCaseBitFieldMask =
413
509
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
415
virtual MaybeObject* GetElementStubWithoutMapCheck(
511
virtual Handle<Code> GetElementStubWithoutMapCheck(
416
512
bool is_js_array,
417
ElementsKind elements_kind);
513
ElementsKind elements_kind,
514
KeyedAccessGrowMode grow_mode);
516
virtual bool IsGeneric() const {
517
return target() == *generic_stub();
420
521
virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
422
virtual MaybeObject* ConstructMegamorphicStub(
423
MapList* receiver_maps,
425
StrictModeFlag strict_mode);
523
virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
524
StrictModeFlag strict_mode,
525
KeyedAccessGrowMode grow_mode);
427
virtual Code* string_stub() {
428
return isolate()->builtins()->builtin(
429
Builtins::kKeyedLoadIC_String);
527
virtual Handle<Code> string_stub() {
528
return isolate()->builtins()->KeyedLoadIC_String();
441
540
return Isolate::Current()->builtins()->builtin(
442
541
Builtins::kKeyedLoadIC_Initialize);
444
Code* megamorphic_stub() {
445
return isolate()->builtins()->builtin(
446
Builtins::kKeyedLoadIC_Generic);
448
Code* generic_stub() {
449
return isolate()->builtins()->builtin(
450
Builtins::kKeyedLoadIC_Generic);
452
Code* pre_monomorphic_stub() {
453
return isolate()->builtins()->builtin(
454
Builtins::kKeyedLoadIC_PreMonomorphic);
456
Code* indexed_interceptor_stub() {
457
return isolate()->builtins()->builtin(
458
Builtins::kKeyedLoadIC_IndexedInterceptor);
460
Code* non_strict_arguments_stub() {
461
return isolate()->builtins()->builtin(
462
Builtins::kKeyedLoadIC_NonStrictArguments);
543
Handle<Code> megamorphic_stub() {
544
return isolate()->builtins()->KeyedLoadIC_Generic();
546
Handle<Code> generic_stub() const {
547
return isolate()->builtins()->KeyedLoadIC_Generic();
549
Handle<Code> pre_monomorphic_stub() {
550
return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
552
Handle<Code> indexed_interceptor_stub() {
553
return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
555
Handle<Code> non_strict_arguments_stub() {
556
return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
465
559
static void Clear(Address address, Code* target);
562
666
StrictModeFlag strict_mode);
563
667
static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
564
668
static void GenerateNonStrictArguments(MacroAssembler* masm);
669
static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm);
670
static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm);
566
virtual MaybeObject* GetElementStubWithoutMapCheck(
672
virtual Handle<Code> GetElementStubWithoutMapCheck(
567
673
bool is_js_array,
568
ElementsKind elements_kind);
674
ElementsKind elements_kind,
675
KeyedAccessGrowMode grow_mode);
677
virtual bool IsGeneric() const {
678
return target() == *generic_stub() ||
679
target() == *generic_stub_strict();
571
683
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
573
virtual MaybeObject* ConstructMegamorphicStub(
574
MapList* receiver_maps,
576
StrictModeFlag strict_mode);
685
virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
686
StrictModeFlag strict_mode,
687
KeyedAccessGrowMode grow_mode);
579
690
// Update the inline cache.
596
707
return Isolate::Current()->builtins()->builtin(
597
708
Builtins::kKeyedStoreIC_Initialize);
599
Code* megamorphic_stub() {
600
return isolate()->builtins()->builtin(
601
Builtins::kKeyedStoreIC_Generic);
603
710
static Code* initialize_stub_strict() {
604
711
return Isolate::Current()->builtins()->builtin(
605
712
Builtins::kKeyedStoreIC_Initialize_Strict);
607
Code* megamorphic_stub_strict() {
608
return isolate()->builtins()->builtin(
609
Builtins::kKeyedStoreIC_Generic_Strict);
611
Code* generic_stub() {
612
return isolate()->builtins()->builtin(
613
Builtins::kKeyedStoreIC_Generic);
615
Code* generic_stub_strict() {
616
return isolate()->builtins()->builtin(
617
Builtins::kKeyedStoreIC_Generic_Strict);
619
Code* non_strict_arguments_stub() {
620
return isolate()->builtins()->builtin(
621
Builtins::kKeyedStoreIC_NonStrictArguments);
714
Handle<Code> megamorphic_stub() {
715
return isolate()->builtins()->KeyedStoreIC_Generic();
717
Handle<Code> megamorphic_stub_strict() {
718
return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
720
Handle<Code> generic_stub() const {
721
return isolate()->builtins()->KeyedStoreIC_Generic();
723
Handle<Code> generic_stub_strict() const {
724
return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
726
Handle<Code> non_strict_arguments_stub() {
727
return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
624
730
static void Clear(Address address, Code* target);
732
StubKind GetStubKind(Handle<JSObject> receiver,
734
Handle<Object> value);