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/mips/ic-mips.cc

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

Powered by Google App Engine
This is Rietveld 408576698