| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 8606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8617 frame_->SetElementAt(0, &answer); | 8617 frame_->SetElementAt(0, &answer); |
| 8618 } | 8618 } |
| 8619 | 8619 |
| 8620 | 8620 |
| 8621 void InstanceofStub::Generate(MacroAssembler* masm) { | 8621 void InstanceofStub::Generate(MacroAssembler* masm) { |
| 8622 // Implements "value instanceof function" operator. | 8622 // Implements "value instanceof function" operator. |
| 8623 // Expected input state: | 8623 // Expected input state: |
| 8624 // rsp[0] : return address | 8624 // rsp[0] : return address |
| 8625 // rsp[1] : function pointer | 8625 // rsp[1] : function pointer |
| 8626 // rsp[2] : value | 8626 // rsp[2] : value |
| 8627 // Returns a bitwise zero to indicate that the value |
| 8628 // is and instance of the function and anything else to |
| 8629 // indicate that the value is not an instance. |
| 8627 | 8630 |
| 8628 // Get the object - go slow case if it's a smi. | 8631 // Get the object - go slow case if it's a smi. |
| 8629 Label slow; | 8632 Label slow; |
| 8630 __ movq(rax, Operand(rsp, 2 * kPointerSize)); | 8633 __ movq(rax, Operand(rsp, 2 * kPointerSize)); |
| 8631 __ JumpIfSmi(rax, &slow); | 8634 __ JumpIfSmi(rax, &slow); |
| 8632 | 8635 |
| 8633 // Check that the left hand is a JS object. Leave its map in rax. | 8636 // Check that the left hand is a JS object. Leave its map in rax. |
| 8634 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax); | 8637 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax); |
| 8635 __ j(below, &slow); | 8638 __ j(below, &slow); |
| 8636 __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE); | 8639 __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE); |
| 8637 __ j(above, &slow); | 8640 __ j(above, &slow); |
| 8638 | 8641 |
| 8639 // Get the prototype of the function. | 8642 // Get the prototype of the function. |
| 8640 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); | 8643 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); |
| 8644 // rdx is function, rax is map. |
| 8645 |
| 8646 // Look up the function and the map in the instanceof cache. |
| 8647 Label miss; |
| 8648 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); |
| 8649 __ j(not_equal, &miss); |
| 8650 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex); |
| 8651 __ j(not_equal, &miss); |
| 8652 __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); |
| 8653 __ ret(2 * kPointerSize); |
| 8654 |
| 8655 __ bind(&miss); |
| 8641 __ TryGetFunctionPrototype(rdx, rbx, &slow); | 8656 __ TryGetFunctionPrototype(rdx, rbx, &slow); |
| 8642 | 8657 |
| 8643 // Check that the function prototype is a JS object. | 8658 // Check that the function prototype is a JS object. |
| 8644 __ JumpIfSmi(rbx, &slow); | 8659 __ JumpIfSmi(rbx, &slow); |
| 8645 __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister); | 8660 __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister); |
| 8646 __ j(below, &slow); | 8661 __ j(below, &slow); |
| 8647 __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE); | 8662 __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE); |
| 8648 __ j(above, &slow); | 8663 __ j(above, &slow); |
| 8649 | 8664 |
| 8650 // Register mapping: rax is object map and rbx is function prototype. | 8665 // Register mapping: |
| 8666 // rax is object map. |
| 8667 // rdx is function. |
| 8668 // rbx is function prototype. |
| 8669 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); |
| 8670 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex); |
| 8671 |
| 8651 __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset)); | 8672 __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset)); |
| 8652 | 8673 |
| 8653 // Loop through the prototype chain looking for the function prototype. | 8674 // Loop through the prototype chain looking for the function prototype. |
| 8654 Label loop, is_instance, is_not_instance; | 8675 Label loop, is_instance, is_not_instance; |
| 8655 __ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex); | 8676 __ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex); |
| 8656 __ bind(&loop); | 8677 __ bind(&loop); |
| 8657 __ cmpq(rcx, rbx); | 8678 __ cmpq(rcx, rbx); |
| 8658 __ j(equal, &is_instance); | 8679 __ j(equal, &is_instance); |
| 8659 __ cmpq(rcx, kScratchRegister); | 8680 __ cmpq(rcx, kScratchRegister); |
| 8681 // The code at is_not_instance assumes that kScratchRegister contains a |
| 8682 // non-zero GCable value (the null object in this case). |
| 8660 __ j(equal, &is_not_instance); | 8683 __ j(equal, &is_not_instance); |
| 8661 __ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset)); | 8684 __ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset)); |
| 8662 __ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset)); | 8685 __ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset)); |
| 8663 __ jmp(&loop); | 8686 __ jmp(&loop); |
| 8664 | 8687 |
| 8665 __ bind(&is_instance); | 8688 __ bind(&is_instance); |
| 8666 __ xorl(rax, rax); | 8689 __ xorl(rax, rax); |
| 8690 // Store bitwise zero in the cache. This is a Smi in GC terms. |
| 8691 ASSERT_EQ(0, kSmiTag); |
| 8692 __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); |
| 8667 __ ret(2 * kPointerSize); | 8693 __ ret(2 * kPointerSize); |
| 8668 | 8694 |
| 8669 __ bind(&is_not_instance); | 8695 __ bind(&is_not_instance); |
| 8670 __ movl(rax, Immediate(1)); | 8696 // We have to store a non-zero value in the cache. |
| 8697 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); |
| 8671 __ ret(2 * kPointerSize); | 8698 __ ret(2 * kPointerSize); |
| 8672 | 8699 |
| 8673 // Slow-case: Go through the JavaScript implementation. | 8700 // Slow-case: Go through the JavaScript implementation. |
| 8674 __ bind(&slow); | 8701 __ bind(&slow); |
| 8675 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 8702 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 8676 } | 8703 } |
| 8677 | 8704 |
| 8678 | 8705 |
| 8679 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { | 8706 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
| 8680 // rsp[0] : return address | 8707 // rsp[0] : return address |
| (...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11235 // Call the function from C++. | 11262 // Call the function from C++. |
| 11236 return FUNCTION_CAST<ModuloFunction>(buffer); | 11263 return FUNCTION_CAST<ModuloFunction>(buffer); |
| 11237 } | 11264 } |
| 11238 | 11265 |
| 11239 #endif | 11266 #endif |
| 11240 | 11267 |
| 11241 | 11268 |
| 11242 #undef __ | 11269 #undef __ |
| 11243 | 11270 |
| 11244 } } // namespace v8::internal | 11271 } } // namespace v8::internal |
| OLD | NEW |