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