OLD | NEW |
---|---|
1 // Copyright 2012 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 |
(...skipping 1110 matching lines...) Loading... | |
1121 __ pshufd(input, input, static_cast<uint8_t>(0xe1)); // Order: 11 10 00 01 | 1121 __ pshufd(input, input, static_cast<uint8_t>(0xe1)); // Order: 11 10 00 01 |
1122 __ movdbl(double_scratch, Operand::StaticArray( | 1122 __ movdbl(double_scratch, Operand::StaticArray( |
1123 temp2, times_8, ExternalReference::math_exp_log_table())); | 1123 temp2, times_8, ExternalReference::math_exp_log_table())); |
1124 __ por(input, double_scratch); | 1124 __ por(input, double_scratch); |
1125 __ mulsd(result, input); | 1125 __ mulsd(result, input); |
1126 __ bind(&done); | 1126 __ bind(&done); |
1127 } | 1127 } |
1128 | 1128 |
1129 #undef __ | 1129 #undef __ |
1130 | 1130 |
1131 static const int kNoCodeAgeSequenceLength = 5; | 1131 static const int kCodeAgeSequenceLength = 6; |
1132 | 1132 |
1133 static byte* GetNoCodeAgeSequence(uint32_t* length) { | 1133 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
1134 static bool initialized = false; | 1134 static bool initialized = false; |
1135 static byte sequence[kNoCodeAgeSequenceLength]; | 1135 static byte sequence[kCodeAgeSequenceLength]; |
1136 *length = kNoCodeAgeSequenceLength; | 1136 *length = kCodeAgeSequenceLength; |
1137 if (!initialized) { | 1137 if (!initialized) { |
1138 // The sequence of instructions that is patched out for aging code is the | 1138 // The sequence of instructions that is patched out for aging code is the |
1139 // following boilerplate stack-building prologue that is found both in | 1139 // following boilerplate stack-building prologue that is found both in |
1140 // FUNCTION and OPTIMIZED_FUNCTION code: | 1140 // FUNCTION and OPTIMIZED_FUNCTION code: |
1141 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); | 1141 CodePatcher patcher(sequence, kCodeAgeSequenceLength); |
1142 patcher.masm()->push(ebp); | 1142 patcher.masm()->push(ebp); |
1143 patcher.masm()->mov(ebp, esp); | 1143 patcher.masm()->mov(ebp, esp); |
1144 patcher.masm()->push(esi); | 1144 patcher.masm()->push(esi); |
1145 patcher.masm()->push(edi); | 1145 patcher.masm()->push(edi); |
1146 patcher.masm()->nop(); | |
rmcilroy
2013/09/11 15:28:28
If you have any ideas for how to distingish betwee
| |
1146 initialized = true; | 1147 initialized = true; |
1147 } | 1148 } |
1148 return sequence; | 1149 return sequence; |
1150 } | |
1151 | |
1152 | |
1153 static byte* GetPreAgedCodeAgeSequence(uint32_t* length) { | |
1154 static bool initialized = false; | |
1155 static byte sequence[kCodeAgeSequenceLength]; | |
1156 *length = kCodeAgeSequenceLength; | |
1157 if (!initialized) { | |
1158 // If code is "pre-aged" then this sequence of instructions is found in the | |
1159 // boilerplate stack-building prologue that is found in FUNCTIONS and | |
1160 // OPTIMIZED_FUNCTION code, and is patched out for code aging. | |
1161 CodePatcher patcher(sequence, kCodeAgeSequenceLength); | |
1162 patcher.masm()->push(ebp); | |
1163 patcher.masm()->mov(ebp, esp); | |
1164 patcher.masm()->push(esi); | |
1165 patcher.masm()->nop(); | |
1166 patcher.masm()->push(edi); | |
1167 initialized = true; | |
1168 } | |
1169 return sequence; | |
1149 } | 1170 } |
1150 | 1171 |
1151 | 1172 |
1152 bool Code::IsYoungSequence(byte* sequence) { | 1173 bool Code::IsYoungSequence(byte* sequence) { |
1153 uint32_t young_length; | 1174 uint32_t young_length; |
1154 byte* young_sequence = GetNoCodeAgeSequence(&young_length); | 1175 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
1155 bool result = (!memcmp(sequence, young_sequence, young_length)); | 1176 bool result = (!memcmp(sequence, young_sequence, young_length)); |
1156 ASSERT(result || *sequence == kCallOpcode); | 1177 ASSERT(result || *sequence == kCallOpcode || IsPreAgedSequence(sequence)); |
1157 return result; | 1178 return result; |
1158 } | 1179 } |
1159 | 1180 |
1181 | |
1182 bool Code::IsPreAgedSequence(byte* sequence) { | |
1183 uint32_t pre_aged_length; | |
1184 byte* pre_aged_sequence = GetPreAgedCodeAgeSequence(&pre_aged_length); | |
1185 bool result = (!memcmp(sequence, pre_aged_sequence, pre_aged_length)); | |
1186 ASSERT(result || *sequence == kCallOpcode || IsYoungSequence(sequence)); | |
1187 return result; | |
1188 } | |
1189 | |
1160 | 1190 |
1161 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, | 1191 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
1162 MarkingParity* parity) { | 1192 MarkingParity* parity) { |
1163 if (IsYoungSequence(sequence)) { | 1193 if (IsYoungSequence(sequence)) { |
1164 *age = kNoAge; | 1194 *age = kNoAge; |
1165 *parity = NO_MARKING_PARITY; | 1195 *parity = NO_MARKING_PARITY; |
1196 } else if (IsPreAgedSequence(sequence)) { | |
1197 *age = kPreAgedCodeAge; | |
1198 *parity = NO_MARKING_PARITY; | |
1166 } else { | 1199 } else { |
1167 sequence++; // Skip the kCallOpcode byte | 1200 sequence++; // Skip the kCallOpcode byte |
1168 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + | 1201 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + |
1169 Assembler::kCallTargetAddressOffset; | 1202 Assembler::kCallTargetAddressOffset; |
1170 Code* stub = GetCodeFromTargetAddress(target_address); | 1203 Code* stub = GetCodeFromTargetAddress(target_address); |
1171 GetCodeAgeAndParity(stub, age, parity); | 1204 GetCodeAgeAndParity(stub, age, parity); |
1172 } | 1205 } |
1173 } | 1206 } |
1174 | 1207 |
1175 | 1208 |
1176 void Code::PatchPlatformCodeAge(byte* sequence, | 1209 void Code::PatchPlatformCodeAge(byte* sequence, |
1177 Code::Age age, | 1210 Code::Age age, |
1178 MarkingParity parity) { | 1211 MarkingParity parity) { |
1179 uint32_t young_length; | 1212 uint32_t young_length; |
1180 byte* young_sequence = GetNoCodeAgeSequence(&young_length); | 1213 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
1181 if (age == kNoAge) { | 1214 if (age == kNoAge) { |
1182 CopyBytes(sequence, young_sequence, young_length); | 1215 CopyBytes(sequence, young_sequence, young_length); |
1183 CPU::FlushICache(sequence, young_length); | 1216 CPU::FlushICache(sequence, young_length); |
1184 } else { | 1217 } else { |
1185 Code* stub = GetCodeAgeStub(age, parity); | 1218 Code* stub = GetCodeAgeStub(age, parity); |
1186 CodePatcher patcher(sequence, young_length); | 1219 CodePatcher patcher(sequence, young_length); |
1187 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); | 1220 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); |
1221 patcher.masm()->nop(); | |
1188 } | 1222 } |
1189 } | 1223 } |
1190 | 1224 |
1191 | 1225 |
1192 } } // namespace v8::internal | 1226 } } // namespace v8::internal |
1193 | 1227 |
1194 #endif // V8_TARGET_ARCH_IA32 | 1228 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |