OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 // Probe the stub cache for the value object. | 465 // Probe the stub cache for the value object. |
466 __ bind(&probe); | 466 __ bind(&probe); |
467 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx); | 467 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx); |
468 | 468 |
469 // Cache miss: Jump to runtime. | 469 // Cache miss: Jump to runtime. |
470 __ bind(&miss); | 470 __ bind(&miss); |
471 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); | 471 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); |
472 } | 472 } |
473 | 473 |
474 | 474 |
| 475 static void GenerateNormalHelper(MacroAssembler* masm, |
| 476 int argc, |
| 477 bool is_global_object, |
| 478 Label* miss) { |
| 479 // Search dictionary - put result in register edx. |
| 480 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx); |
| 481 |
| 482 // Move the result to register edi and check that it isn't a smi. |
| 483 __ mov(edi, Operand(edx)); |
| 484 __ test(edx, Immediate(kSmiTagMask)); |
| 485 __ j(zero, miss, not_taken); |
| 486 |
| 487 // Check that the value is a JavaScript function. |
| 488 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 489 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); |
| 490 __ cmp(edx, JS_FUNCTION_TYPE); |
| 491 __ j(not_equal, miss, not_taken); |
| 492 |
| 493 // Patch the receiver with the global proxy if necessary. |
| 494 if (is_global_object) { |
| 495 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 496 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 497 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 498 } |
| 499 |
| 500 // Invoke the function. |
| 501 ParameterCount actual(argc); |
| 502 __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
| 503 } |
| 504 |
| 505 |
475 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 506 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
476 // ----------- S t a t e ------------- | 507 // ----------- S t a t e ------------- |
477 // ----------------------------------- | 508 // ----------------------------------- |
478 | 509 |
479 Label miss, probe, global; | 510 Label miss, global_object, non_global_object; |
480 | 511 |
481 // Get the receiver of the function from the stack; 1 ~ return address. | 512 // Get the receiver of the function from the stack; 1 ~ return address. |
482 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 513 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
483 // Get the name of the function from the stack; 2 ~ return address, receiver. | 514 // Get the name of the function from the stack; 2 ~ return address, receiver. |
484 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize)); | 515 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize)); |
485 | 516 |
486 // Check that the receiver isn't a smi. | 517 // Check that the receiver isn't a smi. |
487 __ test(edx, Immediate(kSmiTagMask)); | 518 __ test(edx, Immediate(kSmiTagMask)); |
488 __ j(zero, &miss, not_taken); | 519 __ j(zero, &miss, not_taken); |
489 | 520 |
490 // Check that the receiver is a valid JS object. | 521 // Check that the receiver is a valid JS object. |
491 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); | 522 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); |
492 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); | 523 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); |
493 __ cmp(eax, FIRST_JS_OBJECT_TYPE); | 524 __ cmp(eax, FIRST_JS_OBJECT_TYPE); |
494 __ j(less, &miss, not_taken); | 525 __ j(less, &miss, not_taken); |
495 | 526 |
496 // If this assert fails, we have to check upper bound too. | 527 // If this assert fails, we have to check upper bound too. |
497 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 528 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
498 | 529 |
499 // Check for access to global proxy. | 530 // Check for access to global object. |
| 531 __ cmp(eax, JS_GLOBAL_OBJECT_TYPE); |
| 532 __ j(equal, &global_object); |
| 533 __ cmp(eax, JS_BUILTINS_OBJECT_TYPE); |
| 534 __ j(not_equal, &non_global_object); |
| 535 |
| 536 // Accessing global object: Load and invoke. |
| 537 __ bind(&global_object); |
| 538 GenerateNormalHelper(masm, argc, true, &miss); |
| 539 |
| 540 // Accessing non-global object: Check for access to global proxy. |
| 541 Label global_proxy, invoke; |
| 542 __ bind(&non_global_object); |
500 __ cmp(eax, JS_GLOBAL_PROXY_TYPE); | 543 __ cmp(eax, JS_GLOBAL_PROXY_TYPE); |
501 __ j(equal, &global, not_taken); | 544 __ j(equal, &global_proxy, not_taken); |
502 | 545 __ bind(&invoke); |
503 // Search the dictionary placing the result in edx. | 546 GenerateNormalHelper(masm, argc, false, &miss); |
504 __ bind(&probe); | |
505 GenerateDictionaryLoad(masm, &miss, eax, edx, ebx, ecx); | |
506 | |
507 // Move the result to register edi and check that it isn't a smi. | |
508 __ mov(edi, Operand(edx)); | |
509 __ test(edx, Immediate(kSmiTagMask)); | |
510 __ j(zero, &miss, not_taken); | |
511 | |
512 // Check that the value is a JavaScript function. | |
513 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); | |
514 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); | |
515 __ cmp(edx, JS_FUNCTION_TYPE); | |
516 __ j(not_equal, &miss, not_taken); | |
517 | |
518 // TODO(120): Check for access to global object. Needs patching of | |
519 // receiver but no security check. | |
520 | |
521 // Invoke the function. | |
522 ParameterCount actual(argc); | |
523 __ InvokeFunction(edi, actual, JUMP_FUNCTION); | |
524 | 547 |
525 // Global object proxy access: Check access rights. | 548 // Global object proxy access: Check access rights. |
526 __ bind(&global); | 549 __ bind(&global_proxy); |
527 __ CheckAccessGlobalProxy(edx, eax, &miss); | 550 __ CheckAccessGlobalProxy(edx, eax, &miss); |
528 __ jmp(&probe); | 551 __ jmp(&invoke); |
529 | 552 |
530 // Cache miss: Jump to runtime. | 553 // Cache miss: Jump to runtime. |
531 __ bind(&miss); | 554 __ bind(&miss); |
532 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); | 555 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); |
533 } | 556 } |
534 | 557 |
535 | 558 |
536 void CallIC::Generate(MacroAssembler* masm, | 559 void CallIC::Generate(MacroAssembler* masm, |
537 int argc, | 560 int argc, |
538 const ExternalReference& f) { | 561 const ExternalReference& f) { |
(...skipping 16 matching lines...) Expand all Loading... |
555 // Call the entry. | 578 // Call the entry. |
556 CEntryStub stub; | 579 CEntryStub stub; |
557 __ mov(Operand(eax), Immediate(2)); | 580 __ mov(Operand(eax), Immediate(2)); |
558 __ mov(Operand(ebx), Immediate(f)); | 581 __ mov(Operand(ebx), Immediate(f)); |
559 __ CallStub(&stub); | 582 __ CallStub(&stub); |
560 | 583 |
561 // Move result to edi and exit the internal frame. | 584 // Move result to edi and exit the internal frame. |
562 __ mov(Operand(edi), eax); | 585 __ mov(Operand(edi), eax); |
563 __ LeaveInternalFrame(); | 586 __ LeaveInternalFrame(); |
564 | 587 |
565 // TODO(120): Check for access to to global object. Needs patching | 588 // Check if the receiver is a global object of some sort. |
566 // of receiver but no security check. | 589 Label invoke, global; |
| 590 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver |
| 591 __ test(edx, Immediate(kSmiTagMask)); |
| 592 __ j(zero, &invoke, not_taken); |
| 593 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 594 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 595 __ cmp(ecx, JS_GLOBAL_OBJECT_TYPE); |
| 596 __ j(equal, &global); |
| 597 __ cmp(ecx, JS_BUILTINS_OBJECT_TYPE); |
| 598 __ j(not_equal, &invoke); |
| 599 |
| 600 // Patch the receiver on the stack. |
| 601 __ bind(&global); |
| 602 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 603 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
567 | 604 |
568 // Invoke the function. | 605 // Invoke the function. |
569 ParameterCount actual(argc); | 606 ParameterCount actual(argc); |
| 607 __ bind(&invoke); |
570 __ InvokeFunction(edi, actual, JUMP_FUNCTION); | 608 __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
571 } | 609 } |
572 | 610 |
573 | 611 |
574 // Defined in ic.cc. | 612 // Defined in ic.cc. |
575 Object* LoadIC_Miss(Arguments args); | 613 Object* LoadIC_Miss(Arguments args); |
576 | 614 |
577 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 615 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
578 // ----------- S t a t e ------------- | 616 // ----------- S t a t e ------------- |
579 // -- ecx : name | 617 // -- ecx : name |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 | 841 |
804 // Do tail-call to runtime routine. | 842 // Do tail-call to runtime routine. |
805 __ TailCallRuntime( | 843 __ TailCallRuntime( |
806 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); | 844 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); |
807 } | 845 } |
808 | 846 |
809 #undef __ | 847 #undef __ |
810 | 848 |
811 | 849 |
812 } } // namespace v8::internal | 850 } } // namespace v8::internal |
OLD | NEW |