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