| 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 |