blob: 10d335eec1ada0b7760a4972325b33de86a0fc04 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian Carlstrome24fa612011-09-29 00:53:55 -070016
17#include "oat.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080018#include "utils.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070019
20#include <zlib.h>
21
22namespace art {
23
24const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
Chao-ying Fu9e369312014-05-21 11:20:52 -070025const uint8_t OatHeader::kOatVersion[] = { '0', '2', '9', '\0' };
Brian Carlstrome24fa612011-09-29 00:53:55 -070026
Elliott Hughesa72ec822012-03-05 17:12:22 -080027OatHeader::OatHeader() {
28 memset(this, 0, sizeof(*this));
29}
30
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070031OatHeader::OatHeader(InstructionSet instruction_set,
Dave Allison70202782013-10-22 17:52:19 -070032 const InstructionSetFeatures& instruction_set_features,
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070033 const std::vector<const DexFile*>* dex_files,
Brian Carlstrom28db0122012-10-18 16:20:41 -070034 uint32_t image_file_location_oat_checksum,
Brian Carlstrom700c8d32012-11-05 10:42:02 -080035 uint32_t image_file_location_oat_data_begin,
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070036 const std::string& image_file_location) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070037 memcpy(magic_, kOatMagic, sizeof(kOatMagic));
38 memcpy(version_, kOatVersion, sizeof(kOatVersion));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070039
Brian Carlstrome24fa612011-09-29 00:53:55 -070040 adler32_checksum_ = adler32(0L, Z_NULL, 0);
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070041
Brian Carlstromf852fb22012-10-19 11:01:58 -070042 CHECK_NE(instruction_set, kNone);
Elliott Hughesa72ec822012-03-05 17:12:22 -080043 instruction_set_ = instruction_set;
44 UpdateChecksum(&instruction_set_, sizeof(instruction_set_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070045
Dave Allison70202782013-10-22 17:52:19 -070046 instruction_set_features_ = instruction_set_features;
47 UpdateChecksum(&instruction_set_features_, sizeof(instruction_set_features_));
48
Brian Carlstrome24fa612011-09-29 00:53:55 -070049 dex_file_count_ = dex_files->size();
50 UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070051
Brian Carlstrom28db0122012-10-18 16:20:41 -070052 image_file_location_oat_checksum_ = image_file_location_oat_checksum;
53 UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_));
54
Brian Carlstrom700c8d32012-11-05 10:42:02 -080055 CHECK(IsAligned<kPageSize>(image_file_location_oat_data_begin));
56 image_file_location_oat_data_begin_ = image_file_location_oat_data_begin;
57 UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070058
59 image_file_location_size_ = image_file_location.size();
60 UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_));
61 UpdateChecksum(image_file_location.data(), image_file_location_size_);
62
Brian Carlstrome24fa612011-09-29 00:53:55 -070063 executable_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070064 interpreter_to_interpreter_bridge_offset_ = 0;
65 interpreter_to_compiled_code_bridge_offset_ = 0;
66 jni_dlsym_lookup_offset_ = 0;
Jeff Hao88474b42013-10-23 16:24:40 -070067 portable_imt_conflict_trampoline_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070068 portable_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070069 portable_to_interpreter_bridge_offset_ = 0;
Andreas Gampe2da88232014-02-27 12:26:20 -080070 quick_generic_jni_trampoline_offset_ = 0;
Jeff Hao88474b42013-10-23 16:24:40 -070071 quick_imt_conflict_trampoline_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070072 quick_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070073 quick_to_interpreter_bridge_offset_ = 0;
Brian Carlstrome24fa612011-09-29 00:53:55 -070074}
75
76bool OatHeader::IsValid() const {
Brian Carlstromf852fb22012-10-19 11:01:58 -070077 if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070078 return false;
79 }
Brian Carlstromf852fb22012-10-19 11:01:58 -070080 if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070081 return false;
82 }
83 return true;
84}
85
86const char* OatHeader::GetMagic() const {
87 CHECK(IsValid());
88 return reinterpret_cast<const char*>(magic_);
89}
90
Brian Carlstrome24fa612011-09-29 00:53:55 -070091uint32_t OatHeader::GetChecksum() const {
92 CHECK(IsValid());
93 return adler32_checksum_;
94}
95
96void OatHeader::UpdateChecksum(const void* data, size_t length) {
97 DCHECK(IsValid());
98 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
99 adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
100}
101
Elliott Hughesa72ec822012-03-05 17:12:22 -0800102InstructionSet OatHeader::GetInstructionSet() const {
103 CHECK(IsValid());
104 return instruction_set_;
105}
106
Dave Allison70202782013-10-22 17:52:19 -0700107const InstructionSetFeatures& OatHeader::GetInstructionSetFeatures() const {
108 CHECK(IsValid());
109 return instruction_set_features_;
110}
111
Brian Carlstrome24fa612011-09-29 00:53:55 -0700112uint32_t OatHeader::GetExecutableOffset() const {
113 DCHECK(IsValid());
Elliott Hughes06b37d92011-10-16 11:51:29 -0700114 DCHECK_ALIGNED(executable_offset_, kPageSize);
Brian Carlstrome24fa612011-09-29 00:53:55 -0700115 CHECK_GT(executable_offset_, sizeof(OatHeader));
116 return executable_offset_;
117}
118
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700119void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
120 DCHECK_ALIGNED(executable_offset, kPageSize);
121 CHECK_GT(executable_offset, sizeof(OatHeader));
122 DCHECK(IsValid());
123 DCHECK_EQ(executable_offset_, 0U);
124
125 executable_offset_ = executable_offset;
126 UpdateChecksum(&executable_offset_, sizeof(executable_offset));
127}
128
Ian Rogers468532e2013-08-05 10:56:33 -0700129const void* OatHeader::GetInterpreterToInterpreterBridge() const {
130 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700131}
132
Ian Rogers468532e2013-08-05 10:56:33 -0700133uint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700134 DCHECK(IsValid());
Dave Allisonc6104ae2014-03-12 11:05:39 -0700135 CHECK(interpreter_to_interpreter_bridge_offset_ == 0 ||
136 interpreter_to_interpreter_bridge_offset_ >= executable_offset_);
Ian Rogers468532e2013-08-05 10:56:33 -0700137 return interpreter_to_interpreter_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700138}
139
Ian Rogers468532e2013-08-05 10:56:33 -0700140void OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700141 CHECK(offset == 0 || offset >= executable_offset_);
142 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700143 DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700144
Ian Rogers468532e2013-08-05 10:56:33 -0700145 interpreter_to_interpreter_bridge_offset_ = offset;
146 UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700147}
148
Ian Rogers468532e2013-08-05 10:56:33 -0700149const void* OatHeader::GetInterpreterToCompiledCodeBridge() const {
150 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700151}
152
Ian Rogers468532e2013-08-05 10:56:33 -0700153uint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700154 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700155 CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_);
156 return interpreter_to_compiled_code_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700157}
158
Ian Rogers468532e2013-08-05 10:56:33 -0700159void OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) {
160 CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700161 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700162 DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700163
Ian Rogers468532e2013-08-05 10:56:33 -0700164 interpreter_to_compiled_code_bridge_offset_ = offset;
165 UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, sizeof(offset));
166}
167
168const void* OatHeader::GetJniDlsymLookup() const {
169 return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset();
170}
171
172uint32_t OatHeader::GetJniDlsymLookupOffset() const {
173 DCHECK(IsValid());
174 CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_);
175 return jni_dlsym_lookup_offset_;
176}
177
178void OatHeader::SetJniDlsymLookupOffset(uint32_t offset) {
179 CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_);
180 DCHECK(IsValid());
181 DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset;
182
183 jni_dlsym_lookup_offset_ = offset;
184 UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700185}
186
Jeff Hao88474b42013-10-23 16:24:40 -0700187const void* OatHeader::GetPortableImtConflictTrampoline() const {
188 return reinterpret_cast<const uint8_t*>(this) + GetPortableImtConflictTrampolineOffset();
189}
190
191uint32_t OatHeader::GetPortableImtConflictTrampolineOffset() const {
192 DCHECK(IsValid());
193 CHECK_GE(portable_imt_conflict_trampoline_offset_, jni_dlsym_lookup_offset_);
194 return portable_imt_conflict_trampoline_offset_;
195}
196
197void OatHeader::SetPortableImtConflictTrampolineOffset(uint32_t offset) {
198 CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_);
199 DCHECK(IsValid());
200 DCHECK_EQ(portable_imt_conflict_trampoline_offset_, 0U) << offset;
201
202 portable_imt_conflict_trampoline_offset_ = offset;
203 UpdateChecksum(&portable_imt_conflict_trampoline_offset_, sizeof(offset));
204}
205
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700206const void* OatHeader::GetPortableResolutionTrampoline() const {
207 return reinterpret_cast<const uint8_t*>(this) + GetPortableResolutionTrampolineOffset();
208}
209
210uint32_t OatHeader::GetPortableResolutionTrampolineOffset() const {
211 DCHECK(IsValid());
Jeff Hao88474b42013-10-23 16:24:40 -0700212 CHECK_GE(portable_resolution_trampoline_offset_, portable_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700213 return portable_resolution_trampoline_offset_;
214}
215
216void OatHeader::SetPortableResolutionTrampolineOffset(uint32_t offset) {
Jeff Hao88474b42013-10-23 16:24:40 -0700217 CHECK(offset == 0 || offset >= portable_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700218 DCHECK(IsValid());
219 DCHECK_EQ(portable_resolution_trampoline_offset_, 0U) << offset;
220
221 portable_resolution_trampoline_offset_ = offset;
222 UpdateChecksum(&portable_resolution_trampoline_offset_, sizeof(offset));
223}
224
Ian Rogers468532e2013-08-05 10:56:33 -0700225const void* OatHeader::GetPortableToInterpreterBridge() const {
226 return reinterpret_cast<const uint8_t*>(this) + GetPortableToInterpreterBridgeOffset();
227}
228
229uint32_t OatHeader::GetPortableToInterpreterBridgeOffset() const {
230 DCHECK(IsValid());
231 CHECK_GE(portable_to_interpreter_bridge_offset_, portable_resolution_trampoline_offset_);
232 return portable_to_interpreter_bridge_offset_;
233}
234
235void OatHeader::SetPortableToInterpreterBridgeOffset(uint32_t offset) {
236 CHECK(offset == 0 || offset >= portable_resolution_trampoline_offset_);
237 DCHECK(IsValid());
238 DCHECK_EQ(portable_to_interpreter_bridge_offset_, 0U) << offset;
239
240 portable_to_interpreter_bridge_offset_ = offset;
241 UpdateChecksum(&portable_to_interpreter_bridge_offset_, sizeof(offset));
242}
243
Andreas Gampe2da88232014-02-27 12:26:20 -0800244const void* OatHeader::GetQuickGenericJniTrampoline() const {
245 return reinterpret_cast<const uint8_t*>(this) + GetQuickGenericJniTrampolineOffset();
246}
247
248uint32_t OatHeader::GetQuickGenericJniTrampolineOffset() const {
249 DCHECK(IsValid());
250 CHECK_GE(quick_generic_jni_trampoline_offset_, portable_to_interpreter_bridge_offset_);
251 return quick_generic_jni_trampoline_offset_;
252}
253
254void OatHeader::SetQuickGenericJniTrampolineOffset(uint32_t offset) {
255 CHECK(offset == 0 || offset >= portable_to_interpreter_bridge_offset_);
256 DCHECK(IsValid());
257 DCHECK_EQ(quick_generic_jni_trampoline_offset_, 0U) << offset;
258
259 quick_generic_jni_trampoline_offset_ = offset;
260 UpdateChecksum(&quick_generic_jni_trampoline_offset_, sizeof(offset));
261}
262
Jeff Hao88474b42013-10-23 16:24:40 -0700263const void* OatHeader::GetQuickImtConflictTrampoline() const {
264 return reinterpret_cast<const uint8_t*>(this) + GetQuickImtConflictTrampolineOffset();
265}
266
267uint32_t OatHeader::GetQuickImtConflictTrampolineOffset() const {
268 DCHECK(IsValid());
Andreas Gampe2da88232014-02-27 12:26:20 -0800269 CHECK_GE(quick_imt_conflict_trampoline_offset_, quick_generic_jni_trampoline_offset_);
Jeff Hao88474b42013-10-23 16:24:40 -0700270 return quick_imt_conflict_trampoline_offset_;
271}
272
273void OatHeader::SetQuickImtConflictTrampolineOffset(uint32_t offset) {
Andreas Gampe2da88232014-02-27 12:26:20 -0800274 CHECK(offset == 0 || offset >= quick_generic_jni_trampoline_offset_);
Jeff Hao88474b42013-10-23 16:24:40 -0700275 DCHECK(IsValid());
276 DCHECK_EQ(quick_imt_conflict_trampoline_offset_, 0U) << offset;
277
278 quick_imt_conflict_trampoline_offset_ = offset;
279 UpdateChecksum(&quick_imt_conflict_trampoline_offset_, sizeof(offset));
280}
281
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700282const void* OatHeader::GetQuickResolutionTrampoline() const {
283 return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset();
284}
285
286uint32_t OatHeader::GetQuickResolutionTrampolineOffset() const {
287 DCHECK(IsValid());
Jeff Hao88474b42013-10-23 16:24:40 -0700288 CHECK_GE(quick_resolution_trampoline_offset_, quick_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700289 return quick_resolution_trampoline_offset_;
290}
291
292void OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) {
Jeff Hao88474b42013-10-23 16:24:40 -0700293 CHECK(offset == 0 || offset >= quick_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700294 DCHECK(IsValid());
295 DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset;
296
297 quick_resolution_trampoline_offset_ = offset;
298 UpdateChecksum(&quick_resolution_trampoline_offset_, sizeof(offset));
299}
300
Ian Rogers468532e2013-08-05 10:56:33 -0700301const void* OatHeader::GetQuickToInterpreterBridge() const {
302 return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset();
303}
304
305uint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const {
306 DCHECK(IsValid());
307 CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_);
308 return quick_to_interpreter_bridge_offset_;
309}
310
311void OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) {
312 CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_);
313 DCHECK(IsValid());
314 DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset;
315
316 quick_to_interpreter_bridge_offset_ = offset;
317 UpdateChecksum(&quick_to_interpreter_bridge_offset_, sizeof(offset));
318}
319
Brian Carlstrom28db0122012-10-18 16:20:41 -0700320uint32_t OatHeader::GetImageFileLocationOatChecksum() const {
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700321 CHECK(IsValid());
Brian Carlstrom28db0122012-10-18 16:20:41 -0700322 return image_file_location_oat_checksum_;
323}
324
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800325uint32_t OatHeader::GetImageFileLocationOatDataBegin() const {
Brian Carlstrom28db0122012-10-18 16:20:41 -0700326 CHECK(IsValid());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800327 return image_file_location_oat_data_begin_;
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700328}
329
330uint32_t OatHeader::GetImageFileLocationSize() const {
331 CHECK(IsValid());
332 return image_file_location_size_;
333}
334
335const uint8_t* OatHeader::GetImageFileLocationData() const {
336 CHECK(IsValid());
337 return image_file_location_data_;
338}
339
340std::string OatHeader::GetImageFileLocation() const {
341 CHECK(IsValid());
342 return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()),
343 GetImageFileLocationSize());
344}
345
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700346OatMethodOffsets::OatMethodOffsets()
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700347 : code_offset_(0),
Jeff Hao74180ca2013-03-27 15:29:11 -0700348 gc_map_offset_(0)
Logan Chienccb7bf12012-03-28 12:52:32 +0800349{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700350
351OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
Jeff Hao74180ca2013-03-27 15:29:11 -0700352 uint32_t gc_map_offset
Logan Chienccb7bf12012-03-28 12:52:32 +0800353 )
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700354 : code_offset_(code_offset),
Jeff Hao74180ca2013-03-27 15:29:11 -0700355 gc_map_offset_(gc_map_offset)
Logan Chienccb7bf12012-03-28 12:52:32 +0800356{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700357
358OatMethodOffsets::~OatMethodOffsets() {}
359
Vladimir Marko7624d252014-05-02 14:40:15 +0100360OatQuickMethodHeader::OatQuickMethodHeader()
Vladimir Marko8a630572014-04-09 18:45:35 +0100361 : mapping_table_offset_(0),
362 vmap_table_offset_(0),
Vladimir Marko7624d252014-05-02 14:40:15 +0100363 frame_info_(0, 0, 0),
Vladimir Marko8a630572014-04-09 18:45:35 +0100364 code_size_(0)
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100365{}
366
Vladimir Marko7624d252014-05-02 14:40:15 +0100367OatQuickMethodHeader::OatQuickMethodHeader(
368 uint32_t mapping_table_offset, uint32_t vmap_table_offset, uint32_t frame_size_in_bytes,
369 uint32_t core_spill_mask, uint32_t fp_spill_mask, uint32_t code_size)
Vladimir Marko8a630572014-04-09 18:45:35 +0100370 : mapping_table_offset_(mapping_table_offset),
371 vmap_table_offset_(vmap_table_offset),
Vladimir Marko7624d252014-05-02 14:40:15 +0100372 frame_info_(frame_size_in_bytes, core_spill_mask, fp_spill_mask),
Vladimir Marko8a630572014-04-09 18:45:35 +0100373 code_size_(code_size)
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100374{}
375
Vladimir Marko7624d252014-05-02 14:40:15 +0100376OatQuickMethodHeader::~OatQuickMethodHeader() {}
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100377
Brian Carlstrome24fa612011-09-29 00:53:55 -0700378} // namespace art