| 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 Label miss; | 131 Label miss; |
| 132 | 132 |
| 133 __ mov(eax, Operand(esp, kPointerSize)); | 133 __ mov(eax, Operand(esp, kPointerSize)); |
| 134 | 134 |
| 135 StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss); | 135 StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss); |
| 136 __ bind(&miss); | 136 __ bind(&miss); |
| 137 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); | 137 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); |
| 138 } | 138 } |
| 139 | 139 |
| 140 | 140 |
| 141 void LoadIC::GenerateShortStringLength(MacroAssembler* masm) { | 141 void LoadIC::GenerateStringLength(MacroAssembler* masm) { |
| 142 // ----------- S t a t e ------------- | 142 // ----------- S t a t e ------------- |
| 143 // -- ecx : name | 143 // -- ecx : name |
| 144 // -- esp[0] : return address | 144 // -- esp[0] : return address |
| 145 // -- esp[4] : receiver | 145 // -- esp[4] : receiver |
| 146 // ----------------------------------- | 146 // ----------------------------------- |
| 147 | 147 |
| 148 Label miss; | 148 Label miss; |
| 149 | 149 |
| 150 __ mov(eax, Operand(esp, kPointerSize)); | 150 __ mov(eax, Operand(esp, kPointerSize)); |
| 151 | 151 |
| 152 StubCompiler::GenerateLoadShortStringLength(masm, eax, edx, &miss); | 152 StubCompiler::GenerateLoadStringLength(masm, eax, edx, &miss); |
| 153 __ bind(&miss); | |
| 154 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); | |
| 155 } | |
| 156 | |
| 157 | |
| 158 void LoadIC::GenerateMediumStringLength(MacroAssembler* masm) { | |
| 159 // ----------- S t a t e ------------- | |
| 160 // -- ecx : name | |
| 161 // -- esp[0] : return address | |
| 162 // -- esp[4] : receiver | |
| 163 // ----------------------------------- | |
| 164 | |
| 165 Label miss; | |
| 166 | |
| 167 __ mov(eax, Operand(esp, kPointerSize)); | |
| 168 | |
| 169 StubCompiler::GenerateLoadMediumStringLength(masm, eax, edx, &miss); | |
| 170 __ bind(&miss); | |
| 171 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); | |
| 172 } | |
| 173 | |
| 174 | |
| 175 void LoadIC::GenerateLongStringLength(MacroAssembler* masm) { | |
| 176 // ----------- S t a t e ------------- | |
| 177 // -- ecx : name | |
| 178 // -- esp[0] : return address | |
| 179 // -- esp[4] : receiver | |
| 180 // ----------------------------------- | |
| 181 | |
| 182 Label miss; | |
| 183 | |
| 184 __ mov(eax, Operand(esp, kPointerSize)); | |
| 185 | |
| 186 StubCompiler::GenerateLoadLongStringLength(masm, eax, edx, &miss); | |
| 187 __ bind(&miss); | 153 __ bind(&miss); |
| 188 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); | 154 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); |
| 189 } | 155 } |
| 190 | 156 |
| 191 | 157 |
| 192 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { | 158 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { |
| 193 // ----------- S t a t e ------------- | 159 // ----------- S t a t e ------------- |
| 194 // -- ecx : name | 160 // -- ecx : name |
| 195 // -- esp[0] : return address | 161 // -- esp[0] : return address |
| 196 // -- esp[4] : receiver | 162 // -- esp[4] : receiver |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 // Probe the stub cache for the value object. | 431 // Probe the stub cache for the value object. |
| 466 __ bind(&probe); | 432 __ bind(&probe); |
| 467 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx); | 433 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx); |
| 468 | 434 |
| 469 // Cache miss: Jump to runtime. | 435 // Cache miss: Jump to runtime. |
| 470 __ bind(&miss); | 436 __ bind(&miss); |
| 471 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); | 437 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); |
| 472 } | 438 } |
| 473 | 439 |
| 474 | 440 |
| 441 static void GenerateNormalHelper(MacroAssembler* masm, |
| 442 int argc, |
| 443 bool is_global_object, |
| 444 Label* miss) { |
| 445 // Search dictionary - put result in register edx. |
| 446 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx); |
| 447 |
| 448 // Move the result to register edi and check that it isn't a smi. |
| 449 __ mov(edi, Operand(edx)); |
| 450 __ test(edx, Immediate(kSmiTagMask)); |
| 451 __ j(zero, miss, not_taken); |
| 452 |
| 453 // Check that the value is a JavaScript function. |
| 454 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 455 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); |
| 456 __ cmp(edx, JS_FUNCTION_TYPE); |
| 457 __ j(not_equal, miss, not_taken); |
| 458 |
| 459 // Patch the receiver with the global proxy if necessary. |
| 460 if (is_global_object) { |
| 461 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 462 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 463 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 464 } |
| 465 |
| 466 // Invoke the function. |
| 467 ParameterCount actual(argc); |
| 468 __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
| 469 } |
| 470 |
| 471 |
| 475 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 472 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
| 476 // ----------- S t a t e ------------- | 473 // ----------- S t a t e ------------- |
| 477 // ----------------------------------- | 474 // ----------------------------------- |
| 478 | 475 |
| 479 Label miss, probe, global; | 476 Label miss, global_object, non_global_object; |
| 480 | 477 |
| 481 // Get the receiver of the function from the stack; 1 ~ return address. | 478 // Get the receiver of the function from the stack; 1 ~ return address. |
| 482 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 479 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 483 // Get the name of the function from the stack; 2 ~ return address, receiver. | 480 // Get the name of the function from the stack; 2 ~ return address, receiver. |
| 484 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize)); | 481 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize)); |
| 485 | 482 |
| 486 // Check that the receiver isn't a smi. | 483 // Check that the receiver isn't a smi. |
| 487 __ test(edx, Immediate(kSmiTagMask)); | 484 __ test(edx, Immediate(kSmiTagMask)); |
| 488 __ j(zero, &miss, not_taken); | 485 __ j(zero, &miss, not_taken); |
| 489 | 486 |
| 490 // Check that the receiver is a valid JS object. | 487 // Check that the receiver is a valid JS object. |
| 491 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); | 488 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); |
| 492 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); | 489 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); |
| 493 __ cmp(eax, FIRST_JS_OBJECT_TYPE); | 490 __ cmp(eax, FIRST_JS_OBJECT_TYPE); |
| 494 __ j(less, &miss, not_taken); | 491 __ j(less, &miss, not_taken); |
| 495 | 492 |
| 496 // If this assert fails, we have to check upper bound too. | 493 // If this assert fails, we have to check upper bound too. |
| 497 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 494 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
| 498 | 495 |
| 499 // Check for access to global proxy. | 496 // Check for access to global object. |
| 497 __ cmp(eax, JS_GLOBAL_OBJECT_TYPE); |
| 498 __ j(equal, &global_object); |
| 499 __ cmp(eax, JS_BUILTINS_OBJECT_TYPE); |
| 500 __ j(not_equal, &non_global_object); |
| 501 |
| 502 // Accessing global object: Load and invoke. |
| 503 __ bind(&global_object); |
| 504 GenerateNormalHelper(masm, argc, true, &miss); |
| 505 |
| 506 // Accessing non-global object: Check for access to global proxy. |
| 507 Label global_proxy, invoke; |
| 508 __ bind(&non_global_object); |
| 500 __ cmp(eax, JS_GLOBAL_PROXY_TYPE); | 509 __ cmp(eax, JS_GLOBAL_PROXY_TYPE); |
| 501 __ j(equal, &global, not_taken); | 510 __ j(equal, &global_proxy, not_taken); |
| 502 | 511 __ bind(&invoke); |
| 503 // Search the dictionary placing the result in edx. | 512 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 | 513 |
| 525 // Global object proxy access: Check access rights. | 514 // Global object proxy access: Check access rights. |
| 526 __ bind(&global); | 515 __ bind(&global_proxy); |
| 527 __ CheckAccessGlobalProxy(edx, eax, &miss); | 516 __ CheckAccessGlobalProxy(edx, eax, &miss); |
| 528 __ jmp(&probe); | 517 __ jmp(&invoke); |
| 529 | 518 |
| 530 // Cache miss: Jump to runtime. | 519 // Cache miss: Jump to runtime. |
| 531 __ bind(&miss); | 520 __ bind(&miss); |
| 532 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); | 521 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); |
| 533 } | 522 } |
| 534 | 523 |
| 535 | 524 |
| 536 void CallIC::Generate(MacroAssembler* masm, | 525 void CallIC::Generate(MacroAssembler* masm, |
| 537 int argc, | 526 int argc, |
| 538 const ExternalReference& f) { | 527 const ExternalReference& f) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 555 // Call the entry. | 544 // Call the entry. |
| 556 CEntryStub stub; | 545 CEntryStub stub; |
| 557 __ mov(Operand(eax), Immediate(2)); | 546 __ mov(Operand(eax), Immediate(2)); |
| 558 __ mov(Operand(ebx), Immediate(f)); | 547 __ mov(Operand(ebx), Immediate(f)); |
| 559 __ CallStub(&stub); | 548 __ CallStub(&stub); |
| 560 | 549 |
| 561 // Move result to edi and exit the internal frame. | 550 // Move result to edi and exit the internal frame. |
| 562 __ mov(Operand(edi), eax); | 551 __ mov(Operand(edi), eax); |
| 563 __ LeaveInternalFrame(); | 552 __ LeaveInternalFrame(); |
| 564 | 553 |
| 565 // TODO(120): Check for access to to global object. Needs patching | 554 // Check if the receiver is a global object of some sort. |
| 566 // of receiver but no security check. | 555 Label invoke, global; |
| 556 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver |
| 557 __ test(edx, Immediate(kSmiTagMask)); |
| 558 __ j(zero, &invoke, not_taken); |
| 559 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 560 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 561 __ cmp(ecx, JS_GLOBAL_OBJECT_TYPE); |
| 562 __ j(equal, &global); |
| 563 __ cmp(ecx, JS_BUILTINS_OBJECT_TYPE); |
| 564 __ j(not_equal, &invoke); |
| 565 |
| 566 // Patch the receiver on the stack. |
| 567 __ bind(&global); |
| 568 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 569 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 567 | 570 |
| 568 // Invoke the function. | 571 // Invoke the function. |
| 569 ParameterCount actual(argc); | 572 ParameterCount actual(argc); |
| 573 __ bind(&invoke); |
| 570 __ InvokeFunction(edi, actual, JUMP_FUNCTION); | 574 __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
| 571 } | 575 } |
| 572 | 576 |
| 573 | 577 |
| 574 // Defined in ic.cc. | 578 // Defined in ic.cc. |
| 575 Object* LoadIC_Miss(Arguments args); | 579 Object* LoadIC_Miss(Arguments args); |
| 576 | 580 |
| 577 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 581 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 578 // ----------- S t a t e ------------- | 582 // ----------- S t a t e ------------- |
| 579 // -- ecx : name | 583 // -- ecx : name |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 | 807 |
| 804 // Do tail-call to runtime routine. | 808 // Do tail-call to runtime routine. |
| 805 __ TailCallRuntime( | 809 __ TailCallRuntime( |
| 806 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); | 810 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); |
| 807 } | 811 } |
| 808 | 812 |
| 809 #undef __ | 813 #undef __ |
| 810 | 814 |
| 811 | 815 |
| 812 } } // namespace v8::internal | 816 } } // namespace v8::internal |
| OLD | NEW |