OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 688 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
689 // but may be destroyed if store is successful. | 689 // but may be destroyed if store is successful. |
690 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 690 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
691 Handle<JSObject> object, | 691 Handle<JSObject> object, |
692 int index, | 692 int index, |
693 Handle<Map> transition, | 693 Handle<Map> transition, |
694 Register receiver_reg, | 694 Register receiver_reg, |
695 Register name_reg, | 695 Register name_reg, |
696 Register scratch, | 696 Register scratch, |
697 Label* miss_label) { | 697 Label* miss_label) { |
698 // Check that the object isn't a smi. | |
699 __ JumpIfSmi(receiver_reg, miss_label); | |
700 | |
701 // Check that the map of the object hasn't changed. | 698 // Check that the map of the object hasn't changed. |
702 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 699 __ CheckMap(receiver_reg, Handle<Map>(object->map()), |
703 Immediate(Handle<Map>(object->map()))); | 700 miss_label, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
704 __ j(not_equal, miss_label); | |
705 | 701 |
706 // Perform global security token check if needed. | 702 // Perform global security token check if needed. |
707 if (object->IsJSGlobalProxy()) { | 703 if (object->IsJSGlobalProxy()) { |
708 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 704 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
709 } | 705 } |
710 | 706 |
711 // Stub never generated for non-global objects that require access | 707 // Stub never generated for non-global objects that require access |
712 // checks. | 708 // checks. |
713 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 709 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
714 | 710 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 | 867 |
872 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 868 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
873 reg = holder_reg; // From now on the object will be in holder_reg. | 869 reg = holder_reg; // From now on the object will be in holder_reg. |
874 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 870 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
875 } else { | 871 } else { |
876 bool in_new_space = heap()->InNewSpace(*prototype); | 872 bool in_new_space = heap()->InNewSpace(*prototype); |
877 Handle<Map> current_map(current->map()); | 873 Handle<Map> current_map(current->map()); |
878 if (in_new_space) { | 874 if (in_new_space) { |
879 // Save the map in scratch1 for later. | 875 // Save the map in scratch1 for later. |
880 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 876 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
881 __ cmp(scratch1, Immediate(current_map)); | |
882 } else { | |
883 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | |
884 Immediate(current_map)); | |
885 } | 877 } |
886 // Branch on the result of the map check. | 878 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK, |
887 __ j(not_equal, miss); | 879 ALLOW_ELEMENT_TRANSITION_MAPS); |
| 880 |
888 // Check access rights to the global object. This has to happen after | 881 // Check access rights to the global object. This has to happen after |
889 // the map check so that we know that the object is actually a global | 882 // the map check so that we know that the object is actually a global |
890 // object. | 883 // object. |
891 if (current->IsJSGlobalProxy()) { | 884 if (current->IsJSGlobalProxy()) { |
892 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 885 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
893 } | 886 } |
894 reg = holder_reg; // From now on the object will be in holder_reg. | 887 reg = holder_reg; // From now on the object will be in holder_reg. |
895 | 888 |
896 if (in_new_space) { | 889 if (in_new_space) { |
897 // The prototype is in new space; we cannot store a reference to it | 890 // The prototype is in new space; we cannot store a reference to it |
(...skipping 11 matching lines...) Expand all Loading... |
909 | 902 |
910 // Go to the next object in the prototype chain. | 903 // Go to the next object in the prototype chain. |
911 current = prototype; | 904 current = prototype; |
912 } | 905 } |
913 ASSERT(current.is_identical_to(holder)); | 906 ASSERT(current.is_identical_to(holder)); |
914 | 907 |
915 // Log the check depth. | 908 // Log the check depth. |
916 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 909 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
917 | 910 |
918 // Check the holder map. | 911 // Check the holder map. |
919 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 912 __ CheckMap(reg, Handle<Map>(holder->map()), |
920 Immediate(Handle<Map>(holder->map()))); | 913 miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
921 __ j(not_equal, miss); | |
922 | 914 |
923 // Perform security check for access to the global object. | 915 // Perform security check for access to the global object. |
924 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 916 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
925 if (holder->IsJSGlobalProxy()) { | 917 if (holder->IsJSGlobalProxy()) { |
926 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 918 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
927 } | 919 } |
928 | 920 |
929 // If we've skipped any global objects, it's not enough to verify that | 921 // If we've skipped any global objects, it's not enough to verify that |
930 // their maps haven't changed. We also need to check that the property | 922 // their maps haven't changed. We also need to check that the property |
931 // cell for the property is still empty. | 923 // cell for the property is still empty. |
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2396 Handle<AccessorInfo> callback, | 2388 Handle<AccessorInfo> callback, |
2397 Handle<String> name) { | 2389 Handle<String> name) { |
2398 // ----------- S t a t e ------------- | 2390 // ----------- S t a t e ------------- |
2399 // -- eax : value | 2391 // -- eax : value |
2400 // -- ecx : name | 2392 // -- ecx : name |
2401 // -- edx : receiver | 2393 // -- edx : receiver |
2402 // -- esp[0] : return address | 2394 // -- esp[0] : return address |
2403 // ----------------------------------- | 2395 // ----------------------------------- |
2404 Label miss; | 2396 Label miss; |
2405 | 2397 |
2406 // Check that the object isn't a smi. | |
2407 __ JumpIfSmi(edx, &miss); | |
2408 | |
2409 // Check that the map of the object hasn't changed. | 2398 // Check that the map of the object hasn't changed. |
2410 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2399 __ CheckMap(edx, Handle<Map>(object->map()), |
2411 Immediate(Handle<Map>(object->map()))); | 2400 &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
2412 __ j(not_equal, &miss); | |
2413 | 2401 |
2414 // Perform global security token check if needed. | 2402 // Perform global security token check if needed. |
2415 if (object->IsJSGlobalProxy()) { | 2403 if (object->IsJSGlobalProxy()) { |
2416 __ CheckAccessGlobalProxy(edx, ebx, &miss); | 2404 __ CheckAccessGlobalProxy(edx, ebx, &miss); |
2417 } | 2405 } |
2418 | 2406 |
2419 // Stub never generated for non-global objects that require access | 2407 // Stub never generated for non-global objects that require access |
2420 // checks. | 2408 // checks. |
2421 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2409 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2422 | 2410 |
(...skipping 23 matching lines...) Expand all Loading... |
2446 Handle<JSObject> receiver, | 2434 Handle<JSObject> receiver, |
2447 Handle<String> name) { | 2435 Handle<String> name) { |
2448 // ----------- S t a t e ------------- | 2436 // ----------- S t a t e ------------- |
2449 // -- eax : value | 2437 // -- eax : value |
2450 // -- ecx : name | 2438 // -- ecx : name |
2451 // -- edx : receiver | 2439 // -- edx : receiver |
2452 // -- esp[0] : return address | 2440 // -- esp[0] : return address |
2453 // ----------------------------------- | 2441 // ----------------------------------- |
2454 Label miss; | 2442 Label miss; |
2455 | 2443 |
2456 // Check that the object isn't a smi. | |
2457 __ JumpIfSmi(edx, &miss); | |
2458 | |
2459 // Check that the map of the object hasn't changed. | 2444 // Check that the map of the object hasn't changed. |
2460 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2445 __ CheckMap(edx, Handle<Map>(receiver->map()), |
2461 Immediate(Handle<Map>(receiver->map()))); | 2446 &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
2462 __ j(not_equal, &miss); | |
2463 | 2447 |
2464 // Perform global security token check if needed. | 2448 // Perform global security token check if needed. |
2465 if (receiver->IsJSGlobalProxy()) { | 2449 if (receiver->IsJSGlobalProxy()) { |
2466 __ CheckAccessGlobalProxy(edx, ebx, &miss); | 2450 __ CheckAccessGlobalProxy(edx, ebx, &miss); |
2467 } | 2451 } |
2468 | 2452 |
2469 // Stub never generated for non-global objects that require access | 2453 // Stub never generated for non-global objects that require access |
2470 // checks. | 2454 // checks. |
2471 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2455 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); |
2472 | 2456 |
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3831 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3815 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3832 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3816 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3833 } | 3817 } |
3834 | 3818 |
3835 | 3819 |
3836 #undef __ | 3820 #undef __ |
3837 | 3821 |
3838 } } // namespace v8::internal | 3822 } } // namespace v8::internal |
3839 | 3823 |
3840 #endif // V8_TARGET_ARCH_IA32 | 3824 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |