Chromium Code Reviews| 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 |