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 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
926 | 926 |
927 void MacroAssembler::AllocateInNewSpace(int object_size, | 927 void MacroAssembler::AllocateInNewSpace(int object_size, |
928 Register result, | 928 Register result, |
929 Register scratch1, | 929 Register scratch1, |
930 Register scratch2, | 930 Register scratch2, |
931 Label* gc_required, | 931 Label* gc_required, |
932 AllocationFlags flags) { | 932 AllocationFlags flags) { |
933 ASSERT(!result.is(scratch1)); | 933 ASSERT(!result.is(scratch1)); |
934 ASSERT(!scratch1.is(scratch2)); | 934 ASSERT(!scratch1.is(scratch2)); |
935 | 935 |
936 // Make object size into bytes. | |
937 if ((flags & SIZE_IN_WORDS) != 0) { | |
938 object_size *= kPointerSize; | |
939 } | |
940 | |
936 // Load address of new object into result and allocation top address into | 941 // Load address of new object into result and allocation top address into |
937 // scratch1. | 942 // scratch1. |
938 ExternalReference new_space_allocation_top = | 943 ExternalReference new_space_allocation_top = |
939 ExternalReference::new_space_allocation_top_address(); | 944 ExternalReference::new_space_allocation_top_address(); |
940 mov(scratch1, Operand(new_space_allocation_top)); | 945 mov(scratch1, Operand(new_space_allocation_top)); |
941 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 946 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
942 ldr(result, MemOperand(scratch1)); | 947 ldr(result, MemOperand(scratch1)); |
943 } else if (FLAG_debug_code) { | 948 } else if (FLAG_debug_code) { |
944 // Assert that result actually contains top on entry. scratch2 is used | 949 // Assert that result actually contains top on entry. scratch2 is used |
945 // immediately below so this use of scratch2 does not cause difference with | 950 // immediately below so this use of scratch2 does not cause difference with |
946 // respect to register content between debug and release mode. | 951 // respect to register content between debug and release mode. |
947 ldr(scratch2, MemOperand(scratch1)); | 952 ldr(scratch2, MemOperand(scratch1)); |
948 cmp(result, scratch2); | 953 cmp(result, scratch2); |
949 Check(eq, "Unexpected allocation top"); | 954 Check(eq, "Unexpected allocation top"); |
950 } | 955 } |
951 | 956 |
952 // Calculate new top and bail out if new space is exhausted. Use result | 957 // Calculate new top and bail out if new space is exhausted. Use result |
953 // to calculate the new top. | 958 // to calculate the new top. |
954 ExternalReference new_space_allocation_limit = | 959 ExternalReference new_space_allocation_limit = |
955 ExternalReference::new_space_allocation_limit_address(); | 960 ExternalReference::new_space_allocation_limit_address(); |
956 mov(scratch2, Operand(new_space_allocation_limit)); | 961 mov(scratch2, Operand(new_space_allocation_limit)); |
957 ldr(scratch2, MemOperand(scratch2)); | 962 ldr(scratch2, MemOperand(scratch2)); |
958 add(result, result, Operand(object_size * kPointerSize)); | 963 add(result, result, Operand(object_size)); |
Vyacheslav Egorov (Chromium)
2010/05/07 13:18:26
May be add some ASSERTion on object_size alignment
| |
959 cmp(result, Operand(scratch2)); | 964 cmp(result, Operand(scratch2)); |
960 b(hi, gc_required); | 965 b(hi, gc_required); |
961 | 966 |
962 // Update allocation top. result temporarily holds the new top. | 967 // Update allocation top. result temporarily holds the new top. |
963 if (FLAG_debug_code) { | 968 if (FLAG_debug_code) { |
964 tst(result, Operand(kObjectAlignmentMask)); | 969 tst(result, Operand(kObjectAlignmentMask)); |
965 Check(eq, "Unaligned allocation in new space"); | 970 Check(eq, "Unaligned allocation in new space"); |
966 } | 971 } |
967 str(result, MemOperand(scratch1)); | 972 str(result, MemOperand(scratch1)); |
968 | 973 |
969 // Tag and adjust back to start of new object. | 974 // Tag and adjust back to start of new object. |
970 if ((flags & TAG_OBJECT) != 0) { | 975 if ((flags & TAG_OBJECT) != 0) { |
971 sub(result, result, Operand((object_size * kPointerSize) - | 976 sub(result, result, Operand(object_size - kHeapObjectTag)); |
972 kHeapObjectTag)); | |
973 } else { | 977 } else { |
974 sub(result, result, Operand(object_size * kPointerSize)); | 978 sub(result, result, Operand(object_size)); |
975 } | 979 } |
976 } | 980 } |
977 | 981 |
978 | 982 |
979 void MacroAssembler::AllocateInNewSpace(Register object_size, | 983 void MacroAssembler::AllocateInNewSpace(Register object_size, |
980 Register result, | 984 Register result, |
981 Register scratch1, | 985 Register scratch1, |
982 Register scratch2, | 986 Register scratch2, |
983 Label* gc_required, | 987 Label* gc_required, |
984 AllocationFlags flags) { | 988 AllocationFlags flags) { |
(...skipping 16 matching lines...) Expand all Loading... | |
1001 Check(eq, "Unexpected allocation top"); | 1005 Check(eq, "Unexpected allocation top"); |
1002 } | 1006 } |
1003 | 1007 |
1004 // Calculate new top and bail out if new space is exhausted. Use result | 1008 // Calculate new top and bail out if new space is exhausted. Use result |
1005 // to calculate the new top. Object size is in words so a shift is required to | 1009 // to calculate the new top. Object size is in words so a shift is required to |
1006 // get the number of bytes | 1010 // get the number of bytes |
1007 ExternalReference new_space_allocation_limit = | 1011 ExternalReference new_space_allocation_limit = |
1008 ExternalReference::new_space_allocation_limit_address(); | 1012 ExternalReference::new_space_allocation_limit_address(); |
1009 mov(scratch2, Operand(new_space_allocation_limit)); | 1013 mov(scratch2, Operand(new_space_allocation_limit)); |
1010 ldr(scratch2, MemOperand(scratch2)); | 1014 ldr(scratch2, MemOperand(scratch2)); |
1011 add(result, result, Operand(object_size, LSL, kPointerSizeLog2)); | 1015 if ((flags & SIZE_IN_WORDS) != 0) { |
1016 add(result, result, Operand(object_size, LSL, kPointerSizeLog2)); | |
1017 } else { | |
1018 add(result, result, Operand(object_size)); | |
1019 } | |
1012 cmp(result, Operand(scratch2)); | 1020 cmp(result, Operand(scratch2)); |
1013 b(hi, gc_required); | 1021 b(hi, gc_required); |
1014 | 1022 |
1015 // Update allocation top. result temporarily holds the new top. | 1023 // Update allocation top. result temporarily holds the new top. |
1016 if (FLAG_debug_code) { | 1024 if (FLAG_debug_code) { |
1017 tst(result, Operand(kObjectAlignmentMask)); | 1025 tst(result, Operand(kObjectAlignmentMask)); |
1018 Check(eq, "Unaligned allocation in new space"); | 1026 Check(eq, "Unaligned allocation in new space"); |
1019 } | 1027 } |
1020 str(result, MemOperand(scratch1)); | 1028 str(result, MemOperand(scratch1)); |
1021 | 1029 |
1022 // Adjust back to start of new object. | 1030 // Adjust back to start of new object. |
1023 sub(result, result, Operand(object_size, LSL, kPointerSizeLog2)); | 1031 if ((flags & SIZE_IN_WORDS) != 0) { |
1032 sub(result, result, Operand(object_size, LSL, kPointerSizeLog2)); | |
1033 } else { | |
1034 sub(result, result, Operand(object_size)); | |
1035 } | |
1024 | 1036 |
1025 // Tag object if requested. | 1037 // Tag object if requested. |
1026 if ((flags & TAG_OBJECT) != 0) { | 1038 if ((flags & TAG_OBJECT) != 0) { |
1027 add(result, result, Operand(kHeapObjectTag)); | 1039 add(result, result, Operand(kHeapObjectTag)); |
1028 } | 1040 } |
1029 } | 1041 } |
1030 | 1042 |
1031 | 1043 |
1032 void MacroAssembler::UndoAllocationInNewSpace(Register object, | 1044 void MacroAssembler::UndoAllocationInNewSpace(Register object, |
1033 Register scratch) { | 1045 Register scratch) { |
(...skipping 20 matching lines...) Expand all Loading... | |
1054 Register scratch1, | 1066 Register scratch1, |
1055 Register scratch2, | 1067 Register scratch2, |
1056 Register scratch3, | 1068 Register scratch3, |
1057 Label* gc_required) { | 1069 Label* gc_required) { |
1058 // Calculate the number of bytes needed for the characters in the string while | 1070 // Calculate the number of bytes needed for the characters in the string while |
1059 // observing object alignment. | 1071 // observing object alignment. |
1060 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1072 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
1061 mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars. | 1073 mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars. |
1062 add(scratch1, scratch1, | 1074 add(scratch1, scratch1, |
1063 Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); | 1075 Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); |
1064 // AllocateInNewSpace expects the size in words, so we can round down | 1076 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
1065 // to kObjectAlignment and divide by kPointerSize in the same shift. | |
1066 ASSERT_EQ(kPointerSize, kObjectAlignmentMask + 1); | |
1067 mov(scratch1, Operand(scratch1, ASR, kPointerSizeLog2)); | |
1068 | 1077 |
1069 // Allocate two-byte string in new space. | 1078 // Allocate two-byte string in new space. |
1070 AllocateInNewSpace(scratch1, | 1079 AllocateInNewSpace(scratch1, |
1071 result, | 1080 result, |
1072 scratch2, | 1081 scratch2, |
1073 scratch3, | 1082 scratch3, |
1074 gc_required, | 1083 gc_required, |
1075 TAG_OBJECT); | 1084 TAG_OBJECT); |
1076 | 1085 |
1077 // Set the map, length and hash field. | 1086 // Set the map, length and hash field. |
(...skipping 10 matching lines...) Expand all Loading... | |
1088 Register scratch1, | 1097 Register scratch1, |
1089 Register scratch2, | 1098 Register scratch2, |
1090 Register scratch3, | 1099 Register scratch3, |
1091 Label* gc_required) { | 1100 Label* gc_required) { |
1092 // Calculate the number of bytes needed for the characters in the string while | 1101 // Calculate the number of bytes needed for the characters in the string while |
1093 // observing object alignment. | 1102 // observing object alignment. |
1094 ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0); | 1103 ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0); |
1095 ASSERT(kCharSize == 1); | 1104 ASSERT(kCharSize == 1); |
1096 add(scratch1, length, | 1105 add(scratch1, length, |
1097 Operand(kObjectAlignmentMask + SeqAsciiString::kHeaderSize)); | 1106 Operand(kObjectAlignmentMask + SeqAsciiString::kHeaderSize)); |
1098 // AllocateInNewSpace expects the size in words, so we can round down | 1107 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
1099 // to kObjectAlignment and divide by kPointerSize in the same shift. | |
1100 ASSERT_EQ(kPointerSize, kObjectAlignmentMask + 1); | |
1101 mov(scratch1, Operand(scratch1, ASR, kPointerSizeLog2)); | |
1102 | 1108 |
1103 // Allocate ASCII string in new space. | 1109 // Allocate ASCII string in new space. |
1104 AllocateInNewSpace(scratch1, | 1110 AllocateInNewSpace(scratch1, |
1105 result, | 1111 result, |
1106 scratch2, | 1112 scratch2, |
1107 scratch3, | 1113 scratch3, |
1108 gc_required, | 1114 gc_required, |
1109 TAG_OBJECT); | 1115 TAG_OBJECT); |
1110 | 1116 |
1111 // Set the map, length and hash field. | 1117 // Set the map, length and hash field. |
1112 InitializeNewString(result, | 1118 InitializeNewString(result, |
1113 length, | 1119 length, |
1114 Heap::kAsciiStringMapRootIndex, | 1120 Heap::kAsciiStringMapRootIndex, |
1115 scratch1, | 1121 scratch1, |
1116 scratch2); | 1122 scratch2); |
1117 } | 1123 } |
1118 | 1124 |
1119 | 1125 |
1120 void MacroAssembler::AllocateTwoByteConsString(Register result, | 1126 void MacroAssembler::AllocateTwoByteConsString(Register result, |
1121 Register length, | 1127 Register length, |
1122 Register scratch1, | 1128 Register scratch1, |
1123 Register scratch2, | 1129 Register scratch2, |
1124 Label* gc_required) { | 1130 Label* gc_required) { |
1125 AllocateInNewSpace(ConsString::kSize / kPointerSize, | 1131 AllocateInNewSpace(ConsString::kSize, |
1126 result, | 1132 result, |
1127 scratch1, | 1133 scratch1, |
1128 scratch2, | 1134 scratch2, |
1129 gc_required, | 1135 gc_required, |
1130 TAG_OBJECT); | 1136 TAG_OBJECT); |
1131 | 1137 |
1132 InitializeNewString(result, | 1138 InitializeNewString(result, |
1133 length, | 1139 length, |
1134 Heap::kConsStringMapRootIndex, | 1140 Heap::kConsStringMapRootIndex, |
1135 scratch1, | 1141 scratch1, |
1136 scratch2); | 1142 scratch2); |
1137 } | 1143 } |
1138 | 1144 |
1139 | 1145 |
1140 void MacroAssembler::AllocateAsciiConsString(Register result, | 1146 void MacroAssembler::AllocateAsciiConsString(Register result, |
1141 Register length, | 1147 Register length, |
1142 Register scratch1, | 1148 Register scratch1, |
1143 Register scratch2, | 1149 Register scratch2, |
1144 Label* gc_required) { | 1150 Label* gc_required) { |
1145 AllocateInNewSpace(ConsString::kSize / kPointerSize, | 1151 AllocateInNewSpace(ConsString::kSize, |
1146 result, | 1152 result, |
1147 scratch1, | 1153 scratch1, |
1148 scratch2, | 1154 scratch2, |
1149 gc_required, | 1155 gc_required, |
1150 TAG_OBJECT); | 1156 TAG_OBJECT); |
1151 | 1157 |
1152 InitializeNewString(result, | 1158 InitializeNewString(result, |
1153 length, | 1159 length, |
1154 Heap::kConsAsciiStringMapRootIndex, | 1160 Heap::kConsAsciiStringMapRootIndex, |
1155 scratch1, | 1161 scratch1, |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1549 | 1555 |
1550 | 1556 |
1551 // Allocates a heap number or jumps to the need_gc label if the young space | 1557 // Allocates a heap number or jumps to the need_gc label if the young space |
1552 // is full and a scavenge is needed. | 1558 // is full and a scavenge is needed. |
1553 void MacroAssembler::AllocateHeapNumber(Register result, | 1559 void MacroAssembler::AllocateHeapNumber(Register result, |
1554 Register scratch1, | 1560 Register scratch1, |
1555 Register scratch2, | 1561 Register scratch2, |
1556 Label* gc_required) { | 1562 Label* gc_required) { |
1557 // Allocate an object in the heap for the heap number and tag it as a heap | 1563 // Allocate an object in the heap for the heap number and tag it as a heap |
1558 // object. | 1564 // object. |
1559 AllocateInNewSpace(HeapNumber::kSize / kPointerSize, | 1565 AllocateInNewSpace(HeapNumber::kSize, |
1560 result, | 1566 result, |
1561 scratch1, | 1567 scratch1, |
1562 scratch2, | 1568 scratch2, |
1563 gc_required, | 1569 gc_required, |
1564 TAG_OBJECT); | 1570 TAG_OBJECT); |
1565 | 1571 |
1566 // Get heap number map and store it in the allocated object. | 1572 // Get heap number map and store it in the allocated object. |
1567 LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex); | 1573 LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex); |
1568 str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); | 1574 str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); |
1569 } | 1575 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1717 } | 1723 } |
1718 | 1724 |
1719 | 1725 |
1720 void CodePatcher::Emit(Address addr) { | 1726 void CodePatcher::Emit(Address addr) { |
1721 masm()->emit(reinterpret_cast<Instr>(addr)); | 1727 masm()->emit(reinterpret_cast<Instr>(addr)); |
1722 } | 1728 } |
1723 #endif // ENABLE_DEBUGGER_SUPPORT | 1729 #endif // ENABLE_DEBUGGER_SUPPORT |
1724 | 1730 |
1725 | 1731 |
1726 } } // namespace v8::internal | 1732 } } // namespace v8::internal |
OLD | NEW |