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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
913 // Trash the registers to simulate an allocation failure. | 913 // Trash the registers to simulate an allocation failure. |
914 mov(result, Operand(0x7091)); | 914 mov(result, Operand(0x7091)); |
915 mov(scratch1, Operand(0x7191)); | 915 mov(scratch1, Operand(0x7191)); |
916 mov(scratch2, Operand(0x7291)); | 916 mov(scratch2, Operand(0x7291)); |
917 } | 917 } |
918 jmp(gc_required); | 918 jmp(gc_required); |
919 return; | 919 return; |
920 } | 920 } |
921 | 921 |
922 ASSERT(!result.is(scratch1)); | 922 ASSERT(!result.is(scratch1)); |
923 ASSERT(!result.is(scratch2)); | |
923 ASSERT(!scratch1.is(scratch2)); | 924 ASSERT(!scratch1.is(scratch2)); |
924 | 925 |
925 // Make object size into bytes. | 926 // Make object size into bytes. |
926 if ((flags & SIZE_IN_WORDS) != 0) { | 927 if ((flags & SIZE_IN_WORDS) != 0) { |
927 object_size *= kPointerSize; | 928 object_size *= kPointerSize; |
928 } | 929 } |
929 ASSERT_EQ(0, object_size & kObjectAlignmentMask); | 930 ASSERT_EQ(0, object_size & kObjectAlignmentMask); |
930 | 931 |
931 // Load address of new object into result and allocation top address into | 932 // Check relative positions of allocation top and limit addresses. |
932 // scratch1. | 933 // The values must be adjacent in memory to allow the use of LDM. |
934 // Also, assert that the registers are numbered such that the values | |
935 // are loaded in the correct order. | |
933 ExternalReference new_space_allocation_top = | 936 ExternalReference new_space_allocation_top = |
934 ExternalReference::new_space_allocation_top_address(); | 937 ExternalReference::new_space_allocation_top_address(); |
935 mov(scratch1, Operand(new_space_allocation_top)); | 938 ExternalReference new_space_allocation_limit = |
939 ExternalReference::new_space_allocation_limit_address(); | |
940 uint32_t top = | |
941 reinterpret_cast<uint32_t>(new_space_allocation_top.address()); | |
942 uint32_t limit = | |
943 reinterpret_cast<uint32_t>(new_space_allocation_limit.address()); | |
944 ASSERT((limit - top) == 4); | |
Erik Corry
2010/12/06 09:40:06
Prefer kPointerSize to 4 since it tells the reader
| |
945 ASSERT(result.code() < ip.code()); | |
946 | |
947 // Set up allocation top address and object size registers. | |
948 Register topaddr = scratch1; | |
949 Register obj_size_reg = scratch2; | |
950 mov(topaddr, Operand(new_space_allocation_top)); | |
951 mov(obj_size_reg, Operand(object_size)); | |
952 | |
953 // This code stores a temporary value in ip. This is OK, as the code below | |
954 // does not need ip for implicit literal generation. | |
936 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 955 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
937 ldr(result, MemOperand(scratch1)); | 956 // Load allocation top into result and allocation limit into ip. |
938 } else if (FLAG_debug_code) { | 957 ldm(ia, topaddr, result.bit() | ip.bit()); |
939 // Assert that result actually contains top on entry. scratch2 is used | 958 } else { |
940 // immediately below so this use of scratch2 does not cause difference with | 959 if (FLAG_debug_code) { |
941 // respect to register content between debug and release mode. | 960 // Assert that result actually contains top on entry. ip is used |
942 ldr(scratch2, MemOperand(scratch1)); | 961 // immediately below so this use of ip does not cause difference with |
943 cmp(result, scratch2); | 962 // respect to register content between debug and release mode. |
944 Check(eq, "Unexpected allocation top"); | 963 ldr(ip, MemOperand(topaddr)); |
964 cmp(result, ip); | |
965 Check(eq, "Unexpected allocation top"); | |
966 } | |
967 // Load allocation limit into ip. Result already contains allocation top. | |
968 ldr(ip, MemOperand(topaddr, limit - top)); | |
945 } | 969 } |
946 | 970 |
947 // Calculate new top and bail out if new space is exhausted. Use result | 971 // Calculate new top and bail out if new space is exhausted. Use result |
948 // to calculate the new top. | 972 // to calculate the new top. |
949 ExternalReference new_space_allocation_limit = | 973 add(scratch2, result, Operand(obj_size_reg)); |
950 ExternalReference::new_space_allocation_limit_address(); | 974 cmp(scratch2, Operand(ip)); |
951 mov(scratch2, Operand(new_space_allocation_limit)); | |
952 ldr(scratch2, MemOperand(scratch2)); | |
953 add(result, result, Operand(object_size)); | |
954 cmp(result, Operand(scratch2)); | |
955 b(hi, gc_required); | 975 b(hi, gc_required); |
956 str(result, MemOperand(scratch1)); | 976 str(scratch2, MemOperand(topaddr)); |
957 | 977 |
958 // Tag and adjust back to start of new object. | 978 // Tag object if requested. |
959 if ((flags & TAG_OBJECT) != 0) { | 979 if ((flags & TAG_OBJECT) != 0) { |
960 sub(result, result, Operand(object_size - kHeapObjectTag)); | 980 add(result, result, Operand(kHeapObjectTag)); |
961 } else { | |
962 sub(result, result, Operand(object_size)); | |
963 } | 981 } |
964 } | 982 } |
965 | 983 |
966 | 984 |
967 void MacroAssembler::AllocateInNewSpace(Register object_size, | 985 void MacroAssembler::AllocateInNewSpace(Register object_size, |
968 Register result, | 986 Register result, |
969 Register scratch1, | 987 Register scratch1, |
970 Register scratch2, | 988 Register scratch2, |
971 Label* gc_required, | 989 Label* gc_required, |
972 AllocationFlags flags) { | 990 AllocationFlags flags) { |
973 if (!FLAG_inline_new) { | 991 if (!FLAG_inline_new) { |
974 if (FLAG_debug_code) { | 992 if (FLAG_debug_code) { |
975 // Trash the registers to simulate an allocation failure. | 993 // Trash the registers to simulate an allocation failure. |
976 mov(result, Operand(0x7091)); | 994 mov(result, Operand(0x7091)); |
977 mov(scratch1, Operand(0x7191)); | 995 mov(scratch1, Operand(0x7191)); |
978 mov(scratch2, Operand(0x7291)); | 996 mov(scratch2, Operand(0x7291)); |
979 } | 997 } |
980 jmp(gc_required); | 998 jmp(gc_required); |
981 return; | 999 return; |
982 } | 1000 } |
983 | 1001 |
984 ASSERT(!result.is(scratch1)); | 1002 ASSERT(!result.is(scratch1)); |
1003 ASSERT(!result.is(scratch2)); | |
985 ASSERT(!scratch1.is(scratch2)); | 1004 ASSERT(!scratch1.is(scratch2)); |
986 | 1005 |
987 // Load address of new object into result and allocation top address into | 1006 // Check relative positions of allocation top and limit addresses. |
988 // scratch1. | 1007 // The values must be adjacent in memory to allow the use of LDM. |
1008 // Also, assert that the registers are numbered such that the values | |
1009 // are loaded in the correct order. | |
989 ExternalReference new_space_allocation_top = | 1010 ExternalReference new_space_allocation_top = |
990 ExternalReference::new_space_allocation_top_address(); | 1011 ExternalReference::new_space_allocation_top_address(); |
991 mov(scratch1, Operand(new_space_allocation_top)); | 1012 ExternalReference new_space_allocation_limit = |
1013 ExternalReference::new_space_allocation_limit_address(); | |
1014 uint32_t top = | |
1015 reinterpret_cast<uint32_t>(new_space_allocation_top.address()); | |
1016 uint32_t limit = | |
1017 reinterpret_cast<uint32_t>(new_space_allocation_limit.address()); | |
1018 ASSERT((limit - top) == 4); | |
1019 ASSERT(result.code() < ip.code()); | |
1020 | |
1021 // Set up allocation top address. | |
1022 Register topaddr = scratch1; | |
1023 mov(topaddr, Operand(new_space_allocation_top)); | |
1024 | |
1025 // This code stores a temporary value in ip. This is OK, as the code below | |
1026 // does not need ip for implicit literal generation. | |
992 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 1027 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
993 ldr(result, MemOperand(scratch1)); | 1028 // Load allocation top into result and allocation limit into ip. |
994 } else if (FLAG_debug_code) { | 1029 ldm(ia, topaddr, result.bit() | ip.bit()); |
995 // Assert that result actually contains top on entry. scratch2 is used | 1030 } else { |
996 // immediately below so this use of scratch2 does not cause difference with | 1031 if (FLAG_debug_code) { |
997 // respect to register content between debug and release mode. | 1032 // Assert that result actually contains top on entry. ip is used |
998 ldr(scratch2, MemOperand(scratch1)); | 1033 // immediately below so this use of ip does not cause difference with |
999 cmp(result, scratch2); | 1034 // respect to register content between debug and release mode. |
1000 Check(eq, "Unexpected allocation top"); | 1035 ldr(ip, MemOperand(topaddr)); |
1036 cmp(result, ip); | |
1037 Check(eq, "Unexpected allocation top"); | |
1038 } | |
1039 // Load allocation limit into ip. Result already contains allocation top. | |
1040 ldr(ip, MemOperand(topaddr, limit - top)); | |
1001 } | 1041 } |
1002 | 1042 |
1003 // Calculate new top and bail out if new space is exhausted. Use result | 1043 // Calculate new top and bail out if new space is exhausted. Use result |
1004 // to calculate the new top. Object size is in words so a shift is required to | 1044 // to calculate the new top. Object size may be in words so a shift is |
1005 // get the number of bytes | 1045 // required to get the number of bytes. |
1006 ExternalReference new_space_allocation_limit = | |
1007 ExternalReference::new_space_allocation_limit_address(); | |
1008 mov(scratch2, Operand(new_space_allocation_limit)); | |
1009 ldr(scratch2, MemOperand(scratch2)); | |
1010 if ((flags & SIZE_IN_WORDS) != 0) { | 1046 if ((flags & SIZE_IN_WORDS) != 0) { |
1011 add(result, result, Operand(object_size, LSL, kPointerSizeLog2)); | 1047 add(scratch2, result, Operand(object_size, LSL, kPointerSizeLog2)); |
1012 } else { | 1048 } else { |
1013 add(result, result, Operand(object_size)); | 1049 add(scratch2, result, Operand(object_size)); |
1014 } | 1050 } |
1015 cmp(result, Operand(scratch2)); | 1051 cmp(scratch2, Operand(ip)); |
1016 b(hi, gc_required); | 1052 b(hi, gc_required); |
1017 | 1053 |
1018 // Update allocation top. result temporarily holds the new top. | 1054 // Update allocation top. result temporarily holds the new top. |
1019 if (FLAG_debug_code) { | 1055 if (FLAG_debug_code) { |
1020 tst(result, Operand(kObjectAlignmentMask)); | 1056 tst(scratch2, Operand(kObjectAlignmentMask)); |
1021 Check(eq, "Unaligned allocation in new space"); | 1057 Check(eq, "Unaligned allocation in new space"); |
1022 } | 1058 } |
1023 str(result, MemOperand(scratch1)); | 1059 str(scratch2, MemOperand(topaddr)); |
1024 | |
1025 // Adjust back to start of new object. | |
1026 if ((flags & SIZE_IN_WORDS) != 0) { | |
1027 sub(result, result, Operand(object_size, LSL, kPointerSizeLog2)); | |
1028 } else { | |
1029 sub(result, result, Operand(object_size)); | |
1030 } | |
1031 | 1060 |
1032 // Tag object if requested. | 1061 // Tag object if requested. |
1033 if ((flags & TAG_OBJECT) != 0) { | 1062 if ((flags & TAG_OBJECT) != 0) { |
1034 add(result, result, Operand(kHeapObjectTag)); | 1063 add(result, result, Operand(kHeapObjectTag)); |
1035 } | 1064 } |
1036 } | 1065 } |
1037 | 1066 |
1038 | 1067 |
1039 void MacroAssembler::UndoAllocationInNewSpace(Register object, | 1068 void MacroAssembler::UndoAllocationInNewSpace(Register object, |
1040 Register scratch) { | 1069 Register scratch) { |
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2002 | 2031 |
2003 void CodePatcher::Emit(Address addr) { | 2032 void CodePatcher::Emit(Address addr) { |
2004 masm()->emit(reinterpret_cast<Instr>(addr)); | 2033 masm()->emit(reinterpret_cast<Instr>(addr)); |
2005 } | 2034 } |
2006 #endif // ENABLE_DEBUGGER_SUPPORT | 2035 #endif // ENABLE_DEBUGGER_SUPPORT |
2007 | 2036 |
2008 | 2037 |
2009 } } // namespace v8::internal | 2038 } } // namespace v8::internal |
2010 | 2039 |
2011 #endif // V8_TARGET_ARCH_ARM | 2040 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |