OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 // Handle load cache miss. | 738 // Handle load cache miss. |
739 __ bind(&miss); | 739 __ bind(&miss); |
740 Handle<Code> ic = ComputeCallMiss(argc); | 740 Handle<Code> ic = ComputeCallMiss(argc); |
741 __ jmp(ic, RelocInfo::CODE_TARGET); | 741 __ jmp(ic, RelocInfo::CODE_TARGET); |
742 | 742 |
743 // Return the generated code. | 743 // Return the generated code. |
744 return GetCode(INTERCEPTOR, name); | 744 return GetCode(INTERCEPTOR, name); |
745 } | 745 } |
746 | 746 |
747 | 747 |
748 Object* CallStubCompiler::CompileCallGlobal(GlobalObject* object, | 748 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, |
| 749 GlobalObject* holder, |
749 JSGlobalPropertyCell* cell, | 750 JSGlobalPropertyCell* cell, |
750 JSFunction* function, | 751 JSFunction* function, |
751 String* name) { | 752 String* name) { |
752 // ----------- S t a t e ------------- | 753 // ----------- S t a t e ------------- |
753 // ----------------------------------- | 754 // ----------------------------------- |
754 Label miss; | 755 Label miss; |
755 | 756 |
756 __ IncrementCounter(&Counters::call_global_inline, 1); | 757 __ IncrementCounter(&Counters::call_global_inline, 1); |
757 | 758 |
758 // Get the number of arguments. | 759 // Get the number of arguments. |
759 const int argc = arguments().immediate(); | 760 const int argc = arguments().immediate(); |
760 | 761 |
761 // Check that the map of the global has not changed. | 762 // Get the receiver from the stack. |
762 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 763 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
763 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 764 |
764 Immediate(Handle<Map>(object->map()))); | 765 // If the object is the holder then we know that it's a global |
765 __ j(not_equal, &miss, not_taken); | 766 // object which can only happen for contextual calls. In this case, |
| 767 // the receiver cannot be a smi. |
| 768 if (object != holder) { |
| 769 __ test(edx, Immediate(kSmiTagMask)); |
| 770 __ j(zero, &miss, not_taken); |
| 771 } |
| 772 |
| 773 // Check that the maps haven't changed. |
| 774 masm()->CheckMaps(object, edx, holder, ebx, ecx, &miss); |
766 | 775 |
767 // Get the value from the cell. | 776 // Get the value from the cell. |
768 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 777 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
769 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | 778 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); |
770 | 779 |
771 // Check that the cell contains the same function. | 780 // Check that the cell contains the same function. |
772 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); | 781 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); |
773 __ j(not_equal, &miss, not_taken); | 782 __ j(not_equal, &miss, not_taken); |
774 | 783 |
775 // Patch the receiver on the stack with the global proxy. | 784 // Patch the receiver on the stack with the global proxy. |
776 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 785 if (object->IsGlobalObject()) { |
777 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 786 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 787 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 788 } |
778 | 789 |
779 // Setup the context (function already in edi). | 790 // Setup the context (function already in edi). |
780 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 791 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
781 | 792 |
782 // Jump to the cached code (tail call). | 793 // Jump to the cached code (tail call). |
783 ASSERT(function->is_compiled()); | 794 ASSERT(function->is_compiled()); |
784 Handle<Code> code(function->code()); | 795 Handle<Code> code(function->code()); |
785 ParameterCount expected(function->shared()->formal_parameter_count()); | 796 ParameterCount expected(function->shared()->formal_parameter_count()); |
786 __ InvokeCode(code, expected, arguments(), | 797 __ InvokeCode(code, expected, arguments(), |
787 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 798 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1115 &miss); | 1126 &miss); |
1116 | 1127 |
1117 __ bind(&miss); | 1128 __ bind(&miss); |
1118 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1129 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1119 | 1130 |
1120 // Return the generated code. | 1131 // Return the generated code. |
1121 return GetCode(INTERCEPTOR, name); | 1132 return GetCode(INTERCEPTOR, name); |
1122 } | 1133 } |
1123 | 1134 |
1124 | 1135 |
1125 Object* LoadStubCompiler::CompileLoadGlobal(GlobalObject* object, | 1136 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
| 1137 GlobalObject* holder, |
1126 JSGlobalPropertyCell* cell, | 1138 JSGlobalPropertyCell* cell, |
1127 String* name, | 1139 String* name, |
1128 bool is_dont_delete) { | 1140 bool is_dont_delete) { |
1129 // ----------- S t a t e ------------- | 1141 // ----------- S t a t e ------------- |
1130 // -- ecx : name | 1142 // -- ecx : name |
1131 // -- esp[0] : return address | 1143 // -- esp[0] : return address |
1132 // -- esp[4] : receiver | 1144 // -- esp[4] : receiver |
1133 // ----------------------------------- | 1145 // ----------------------------------- |
1134 Label miss; | 1146 Label miss; |
1135 | 1147 |
1136 __ IncrementCounter(&Counters::named_load_global_inline, 1); | 1148 __ IncrementCounter(&Counters::named_load_global_inline, 1); |
1137 | 1149 |
1138 // Check that the map of the global has not changed. | 1150 // Get the receiver from the stack. |
1139 __ mov(eax, (Operand(esp, kPointerSize))); | 1151 __ mov(eax, (Operand(esp, kPointerSize))); |
1140 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | 1152 |
1141 Immediate(Handle<Map>(object->map()))); | 1153 // If the object is the holder then we know that it's a global |
1142 __ j(not_equal, &miss, not_taken); | 1154 // object which can only happen for contextual loads. In this case, |
| 1155 // the receiver cannot be a smi. |
| 1156 if (object != holder) { |
| 1157 __ test(eax, Immediate(kSmiTagMask)); |
| 1158 __ j(zero, &miss, not_taken); |
| 1159 } |
| 1160 |
| 1161 // Check that the maps haven't changed. |
| 1162 masm()->CheckMaps(object, eax, holder, ebx, edx, &miss); |
1143 | 1163 |
1144 // Get the value from the cell. | 1164 // Get the value from the cell. |
1145 __ mov(eax, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 1165 __ mov(eax, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
1146 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); | 1166 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); |
1147 | 1167 |
1148 // Check for deleted property if property can actually be deleted. | 1168 // Check for deleted property if property can actually be deleted. |
1149 if (!is_dont_delete) { | 1169 if (!is_dont_delete) { |
1150 __ cmp(eax, Factory::the_hole_value()); | 1170 __ cmp(eax, Factory::the_hole_value()); |
1151 __ j(equal, &miss, not_taken); | 1171 __ j(equal, &miss, not_taken); |
1152 } else if (FLAG_debug_code) { | 1172 } else if (FLAG_debug_code) { |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1386 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1367 | 1387 |
1368 // Return the generated code. | 1388 // Return the generated code. |
1369 return GetCode(CALLBACKS, name); | 1389 return GetCode(CALLBACKS, name); |
1370 } | 1390 } |
1371 | 1391 |
1372 | 1392 |
1373 #undef __ | 1393 #undef __ |
1374 | 1394 |
1375 } } // namespace v8::internal | 1395 } } // namespace v8::internal |
OLD | NEW |