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

Side by Side Diff: src/arm/ic-arm.cc

Issue 148223002: Remove CallICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update test262 status file 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/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 __ b(ne, miss); 97 __ b(ne, miss);
98 98
99 __ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 99 __ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
100 __ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset)); 100 __ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset));
101 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 101 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
102 __ cmp(t1, ip); 102 __ cmp(t1, ip);
103 __ b(ne, miss); 103 __ b(ne, miss);
104 } 104 }
105 105
106 106
107 // Helper function used from LoadIC/CallIC GenerateNormal. 107 // Helper function used from LoadIC GenerateNormal.
108 // 108 //
109 // elements: Property dictionary. It is not clobbered if a jump to the miss 109 // elements: Property dictionary. It is not clobbered if a jump to the miss
110 // label is done. 110 // label is done.
111 // name: Property name. It is not clobbered if a jump to the miss label is 111 // name: Property name. It is not clobbered if a jump to the miss label is
112 // done 112 // done
113 // result: Register for the result. It is only updated if a jump to the miss 113 // result: Register for the result. It is only updated if a jump to the miss
114 // label is not done. Can be the same as elements or name clobbering 114 // label is not done. Can be the same as elements or name clobbering
115 // one of these in the case of not jumping to the miss label. 115 // one of these in the case of not jumping to the miss label.
116 // The two scratch registers need to be different from elements, name and 116 // The two scratch registers need to be different from elements, name and
117 // result. 117 // result.
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 // map: key map 326 // map: key map
327 __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset)); 327 __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset));
328 STATIC_ASSERT(kInternalizedTag == 0); 328 STATIC_ASSERT(kInternalizedTag == 0);
329 __ tst(hash, Operand(kIsNotInternalizedMask)); 329 __ tst(hash, Operand(kIsNotInternalizedMask));
330 __ b(ne, not_unique); 330 __ b(ne, not_unique);
331 331
332 __ bind(&unique); 332 __ bind(&unique);
333 } 333 }
334 334
335 335
336 // Defined in ic.cc. 336 void LoadIC::GenerateMegamorphic(MacroAssembler* masm,
337 Object* CallIC_Miss(Arguments args); 337 ExtraICState extra_state) {
338
339 // The generated code does not accept smi keys.
340 // The generated code falls through if both probes miss.
341 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
342 int argc,
343 Code::Kind kind,
344 ExtraICState extra_state) {
345 // ----------- S t a t e -------------
346 // -- r1 : receiver
347 // -- r2 : name
348 // -----------------------------------
349 Label number, non_number, non_string, boolean, probe, miss;
350
351 // Probe the stub cache.
352 Code::Flags flags = Code::ComputeFlags(kind,
353 MONOMORPHIC,
354 extra_state,
355 Code::NORMAL,
356 argc);
357 masm->isolate()->stub_cache()->GenerateProbe(
358 masm, flags, r1, r2, r3, r4, r5, r6);
359
360 // If the stub cache probing failed, the receiver might be a value.
361 // For value objects, we use the map of the prototype objects for
362 // the corresponding JSValue for the cache and that is what we need
363 // to probe.
364 //
365 // Check for number.
366 __ JumpIfSmi(r1, &number);
367 __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE);
368 __ b(ne, &non_number);
369 __ bind(&number);
370 StubCompiler::GenerateLoadGlobalFunctionPrototype(
371 masm, Context::NUMBER_FUNCTION_INDEX, r1);
372 __ b(&probe);
373
374 // Check for string.
375 __ bind(&non_number);
376 __ cmp(r3, Operand(FIRST_NONSTRING_TYPE));
377 __ b(hs, &non_string);
378 StubCompiler::GenerateLoadGlobalFunctionPrototype(
379 masm, Context::STRING_FUNCTION_INDEX, r1);
380 __ b(&probe);
381
382 // Check for boolean.
383 __ bind(&non_string);
384 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
385 __ cmp(r1, ip);
386 __ b(eq, &boolean);
387 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
388 __ cmp(r1, ip);
389 __ b(ne, &miss);
390 __ bind(&boolean);
391 StubCompiler::GenerateLoadGlobalFunctionPrototype(
392 masm, Context::BOOLEAN_FUNCTION_INDEX, r1);
393
394 // Probe the stub cache for the value object.
395 __ bind(&probe);
396 masm->isolate()->stub_cache()->GenerateProbe(
397 masm, flags, r1, r2, r3, r4, r5, r6);
398
399 __ bind(&miss);
400 }
401
402
403 static void GenerateFunctionTailCall(MacroAssembler* masm,
404 int argc,
405 Label* miss,
406 Register scratch) {
407 // r1: function
408
409 // Check that the value isn't a smi.
410 __ JumpIfSmi(r1, miss);
411
412 // Check that the value is a JSFunction.
413 __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE);
414 __ b(ne, miss);
415
416 // Invoke the function.
417 ParameterCount actual(argc);
418 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
419 }
420
421
422 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) {
423 // ----------- S t a t e ------------- 338 // ----------- S t a t e -------------
424 // -- r2 : name 339 // -- r2 : name
425 // -- lr : return address 340 // -- lr : return address
426 // -----------------------------------
427 Label miss;
428
429 // Get the receiver of the function from the stack into r1.
430 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
431
432 GenerateNameDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss);
433
434 // r0: elements
435 // Search the dictionary - put result in register r1.
436 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4);
437
438 GenerateFunctionTailCall(masm, argc, &miss, r4);
439
440 __ bind(&miss);
441 }
442
443
444 void CallICBase::GenerateMiss(MacroAssembler* masm,
445 int argc,
446 IC::UtilityId id,
447 ExtraICState extra_state) {
448 // ----------- S t a t e -------------
449 // -- r2 : name
450 // -- lr : return address
451 // -----------------------------------
452 Isolate* isolate = masm->isolate();
453
454 if (id == IC::kCallIC_Miss) {
455 __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4);
456 } else {
457 __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4);
458 }
459
460 // Get the receiver of the function from the stack.
461 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
462
463 {
464 FrameScope scope(masm, StackFrame::INTERNAL);
465
466 // Push the receiver and the name of the function.
467 __ Push(r3, r2);
468
469 // Call the entry.
470 __ mov(r0, Operand(2));
471 __ mov(r1, Operand(ExternalReference(IC_Utility(id), isolate)));
472
473 CEntryStub stub(1);
474 __ CallStub(&stub);
475
476 // Move result to r1 and leave the internal frame.
477 __ mov(r1, Operand(r0));
478 }
479
480 // Check if the receiver is a global object of some sort.
481 // This can happen only for regular CallIC but not KeyedCallIC.
482 if (id == IC::kCallIC_Miss) {
483 Label invoke, global;
484 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); // receiver
485 __ JumpIfSmi(r2, &invoke);
486 __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE);
487 __ b(eq, &global);
488 __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE));
489 __ b(ne, &invoke);
490
491 // Patch the receiver on the stack.
492 __ bind(&global);
493 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
494 __ str(r2, MemOperand(sp, argc * kPointerSize));
495 __ bind(&invoke);
496 }
497
498 // Invoke the function.
499 ParameterCount actual(argc);
500 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
501 }
502
503
504 void CallIC::GenerateMegamorphic(MacroAssembler* masm,
505 int argc,
506 ExtraICState extra_ic_state) {
507 // ----------- S t a t e -------------
508 // -- r2 : name
509 // -- lr : return address
510 // -----------------------------------
511
512 // Get the receiver of the function from the stack into r1.
513 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
514 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state);
515 GenerateMiss(masm, argc, extra_ic_state);
516 }
517
518
519 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
520 // ----------- S t a t e -------------
521 // -- r2 : name
522 // -- lr : return address
523 // -----------------------------------
524
525 // Get the receiver of the function from the stack into r1.
526 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
527
528 Label do_call, slow_call, slow_load, slow_reload_receiver;
529 Label check_number_dictionary, check_name, lookup_monomorphic_cache;
530 Label index_smi, index_name;
531
532 // Check that the key is a smi.
533 __ JumpIfNotSmi(r2, &check_name);
534 __ bind(&index_smi);
535 // Now the key is known to be a smi. This place is also jumped to from below
536 // where a numeric string is converted to a smi.
537
538 GenerateKeyedLoadReceiverCheck(
539 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call);
540
541 GenerateFastArrayLoad(
542 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load);
543 Counters* counters = masm->isolate()->counters();
544 __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1, r0, r3);
545
546 __ bind(&do_call);
547 // receiver in r1 is not used after this point.
548 // r2: key
549 // r1: function
550 GenerateFunctionTailCall(masm, argc, &slow_call, r0);
551
552 __ bind(&check_number_dictionary);
553 // r2: key
554 // r3: elements map
555 // r4: elements
556 // Check whether the elements is a number dictionary.
557 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
558 __ cmp(r3, ip);
559 __ b(ne, &slow_load);
560 __ SmiUntag(r0, r2);
561 // r0: untagged index
562 __ LoadFromNumberDictionary(&slow_load, r4, r2, r1, r0, r3, r5);
563 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3);
564 __ jmp(&do_call);
565
566 __ bind(&slow_load);
567 // This branch is taken when calling KeyedCallIC_Miss is neither required
568 // nor beneficial.
569 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3);
570 {
571 FrameScope scope(masm, StackFrame::INTERNAL);
572 __ Push(r2, r1); // save the key and the receiver
573 __ push(r2); // pass the receiver and the key
574 __ CallRuntime(Runtime::kKeyedGetProperty, 2);
575 __ pop(r2); // restore the key
576 }
577 __ mov(r1, r0);
578 __ jmp(&do_call);
579
580 __ bind(&check_name);
581 GenerateKeyNameCheck(masm, r2, r0, r3, &index_name, &slow_call);
582
583 // The key is known to be a unique name.
584 // If the receiver is a regular JS object with slow properties then do
585 // a quick inline probe of the receiver's dictionary.
586 // Otherwise do the monomorphic cache probe.
587 GenerateKeyedLoadReceiverCheck(
588 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
589
590 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset));
591 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset));
592 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
593 __ cmp(r3, ip);
594 __ b(ne, &lookup_monomorphic_cache);
595
596 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4);
597 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3);
598 __ jmp(&do_call);
599
600 __ bind(&lookup_monomorphic_cache);
601 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3);
602 GenerateMonomorphicCacheProbe(masm,
603 argc,
604 Code::KEYED_CALL_IC,
605 kNoExtraICState);
606 // Fall through on miss.
607
608 __ bind(&slow_call);
609 // This branch is taken if:
610 // - the receiver requires boxing or access check,
611 // - the key is neither smi nor a unique name,
612 // - the value loaded is not a function,
613 // - there is hope that the runtime will create a monomorphic call stub
614 // that will get fetched next time.
615 __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3);
616 GenerateMiss(masm, argc);
617
618 __ bind(&index_name);
619 __ IndexFromHash(r3, r2);
620 // Now jump to the place where smi keys are handled.
621 __ jmp(&index_smi);
622 }
623
624
625 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
626 // ----------- S t a t e -------------
627 // -- r2 : name
628 // -- lr : return address
629 // -----------------------------------
630
631 // Check if the name is really a name.
632 Label miss;
633 __ JumpIfSmi(r2, &miss);
634 __ IsObjectNameType(r2, r0, &miss);
635
636 CallICBase::GenerateNormal(masm, argc);
637 __ bind(&miss);
638 GenerateMiss(masm, argc);
639 }
640
641
642 void LoadIC::GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode) {
643 // ----------- S t a t e -------------
644 // -- r2 : name
645 // -- lr : return address
646 // -- r0 : receiver 341 // -- r0 : receiver
647 // ----------------------------------- 342 // -----------------------------------
648 343
649 // Probe the stub cache. 344 // Probe the stub cache.
650 ExtraICState extra_ic_state = LoadIC::ComputeExtraICState(mode);
651 Code::Flags flags = Code::ComputeFlags( 345 Code::Flags flags = Code::ComputeFlags(
652 Code::HANDLER, MONOMORPHIC, extra_ic_state, 346 Code::HANDLER, MONOMORPHIC, extra_state,
653 Code::NORMAL, Code::LOAD_IC); 347 Code::NORMAL, Code::LOAD_IC);
654 masm->isolate()->stub_cache()->GenerateProbe( 348 masm->isolate()->stub_cache()->GenerateProbe(
655 masm, flags, r0, r2, r3, r4, r5, r6); 349 masm, flags, r0, r2, r3, r4, r5, r6);
656 350
657 // Cache miss: Jump to runtime. 351 // Cache miss: Jump to runtime.
658 GenerateMiss(masm); 352 GenerateMiss(masm);
659 } 353 }
660 354
661 355
662 void LoadIC::GenerateNormal(MacroAssembler* masm) { 356 void LoadIC::GenerateNormal(MacroAssembler* masm) {
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 __ str(r0, unmapped_location); 540 __ str(r0, unmapped_location);
847 __ add(r6, r3, r4); 541 __ add(r6, r3, r4);
848 __ mov(r9, r0); 542 __ mov(r9, r0);
849 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs); 543 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs);
850 __ Ret(); 544 __ Ret();
851 __ bind(&slow); 545 __ bind(&slow);
852 GenerateMiss(masm); 546 GenerateMiss(masm);
853 } 547 }
854 548
855 549
856 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
857 int argc) {
858 // ----------- S t a t e -------------
859 // -- r2 : name
860 // -- lr : return address
861 // -----------------------------------
862 Label slow, notin;
863 // Load receiver.
864 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
865 MemOperand mapped_location =
866 GenerateMappedArgumentsLookup(masm, r1, r2, r3, r4, r5, &notin, &slow);
867 __ ldr(r1, mapped_location);
868 GenerateFunctionTailCall(masm, argc, &slow, r3);
869 __ bind(&notin);
870 // The unmapped lookup expects that the parameter map is in r3.
871 MemOperand unmapped_location =
872 GenerateUnmappedArgumentsLookup(masm, r2, r3, r4, &slow);
873 __ ldr(r1, unmapped_location);
874 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
875 __ cmp(r1, r3);
876 __ b(eq, &slow);
877 GenerateFunctionTailCall(masm, argc, &slow, r3);
878 __ bind(&slow);
879 GenerateMiss(masm, argc);
880 }
881
882
883 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 550 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
884 // ---------- S t a t e -------------- 551 // ---------- S t a t e --------------
885 // -- lr : return address 552 // -- lr : return address
886 // -- r0 : key 553 // -- r0 : key
887 // -- r1 : receiver 554 // -- r1 : receiver
888 // ----------------------------------- 555 // -----------------------------------
889 Isolate* isolate = masm->isolate(); 556 Isolate* isolate = masm->isolate();
890 557
891 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); 558 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
892 559
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 } else { 1337 } else {
1671 ASSERT(Assembler::GetCondition(branch_instr) == ne); 1338 ASSERT(Assembler::GetCondition(branch_instr) == ne);
1672 patcher.EmitCondition(eq); 1339 patcher.EmitCondition(eq);
1673 } 1340 }
1674 } 1341 }
1675 1342
1676 1343
1677 } } // namespace v8::internal 1344 } } // namespace v8::internal
1678 1345
1679 #endif // V8_TARGET_ARCH_ARM 1346 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698