OLD | NEW |
---|---|
1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2014 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 DECLARE_GET_MAX_BITFIELD_VALUE_FUNCTION(BlockHeader, body_size); | 43 DECLARE_GET_MAX_BITFIELD_VALUE_FUNCTION(BlockHeader, body_size); |
44 #undef DECLARE_GET_MAX_BITFIELD_VALUE_FUNCTION | 44 #undef DECLARE_GET_MAX_BITFIELD_VALUE_FUNCTION |
45 | 45 |
46 const size_t kMaxBlockHeaderBodySize = GetMaxValueBlockHeader_body_size(); | 46 const size_t kMaxBlockHeaderBodySize = GetMaxValueBlockHeader_body_size(); |
47 | 47 |
48 void InitializeBlockHeader(BlockInfo* block_info) { | 48 void InitializeBlockHeader(BlockInfo* block_info) { |
49 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); | 49 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); |
50 DCHECK_NE(static_cast<BlockHeader*>(NULL), block_info->header); | 50 DCHECK_NE(static_cast<BlockHeader*>(NULL), block_info->header); |
51 ::memset(block_info->header, 0, sizeof(BlockHeader)); | 51 ::memset(block_info->header, 0, sizeof(BlockHeader)); |
52 block_info->header->magic = kBlockHeaderMagic; | 52 block_info->header->magic = kBlockHeaderMagic; |
53 block_info->header->is_nested = block_info->is_nested; | |
54 block_info->header->has_header_padding = block_info->header_padding_size > 0; | 53 block_info->header->has_header_padding = block_info->header_padding_size > 0; |
55 block_info->header->has_excess_trailer_padding = | 54 block_info->header->has_excess_trailer_padding = |
56 block_info->trailer_padding_size > sizeof(uint32_t); | 55 block_info->trailer_padding_size > sizeof(uint32_t); |
57 block_info->header->state = ALLOCATED_BLOCK; | 56 block_info->header->state = ALLOCATED_BLOCK; |
58 block_info->header->body_size = block_info->body_size; | 57 block_info->header->body_size = block_info->body_size; |
59 } | 58 } |
60 | 59 |
61 void InitializeBlockHeaderPadding(BlockInfo* block_info) { | 60 void InitializeBlockHeaderPadding(BlockInfo* block_info) { |
62 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); | 61 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); |
63 if (block_info->header_padding_size == 0) | 62 if (block_info->header_padding_size == 0) |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 BlockTrailer* trailer = reinterpret_cast<BlockTrailer*>( | 179 BlockTrailer* trailer = reinterpret_cast<BlockTrailer*>( |
181 body + header->body_size + trailer_padding_size); | 180 body + header->body_size + trailer_padding_size); |
182 if (!IsAligned(reinterpret_cast<uintptr_t>(trailer + 1), kShadowRatio)) | 181 if (!IsAligned(reinterpret_cast<uintptr_t>(trailer + 1), kShadowRatio)) |
183 return false; | 182 return false; |
184 | 183 |
185 block_info->header = header; | 184 block_info->header = header; |
186 block_info->block_size = reinterpret_cast<uint8_t*>(trailer + 1) - | 185 block_info->block_size = reinterpret_cast<uint8_t*>(trailer + 1) - |
187 reinterpret_cast<uint8_t*>(header); | 186 reinterpret_cast<uint8_t*>(header); |
188 block_info->header_size = sizeof(BlockHeader) + header_padding_size; | 187 block_info->header_size = sizeof(BlockHeader) + header_padding_size; |
189 block_info->trailer_size = trailer_padding_size + sizeof(BlockTrailer); | 188 block_info->trailer_size = trailer_padding_size + sizeof(BlockTrailer); |
190 block_info->is_nested = header->is_nested; | |
191 | 189 |
192 return true; | 190 return true; |
193 } | 191 } |
194 | 192 |
195 BlockHeader* BlockGetHeaderFromBodyImpl(const BlockBody* const_body) { | 193 BlockHeader* BlockGetHeaderFromBodyImpl(const BlockBody* const_body) { |
196 DCHECK_NE(static_cast<BlockBody*>(nullptr), const_body); | 194 DCHECK_NE(static_cast<BlockBody*>(nullptr), const_body); |
197 | 195 |
198 void* body = const_cast<BlockBody*>(const_body); | 196 void* body = const_cast<BlockBody*>(const_body); |
199 | 197 |
200 // The header must be appropriately aligned. | 198 // The header must be appropriately aligned. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 layout->header_size = sizeof(BlockHeader); | 279 layout->header_size = sizeof(BlockHeader); |
282 layout->header_padding_size = left_redzone_size - sizeof(BlockHeader); | 280 layout->header_padding_size = left_redzone_size - sizeof(BlockHeader); |
283 layout->body_size = size; | 281 layout->body_size = size; |
284 layout->trailer_padding_size = right_redzone_size - sizeof(BlockTrailer); | 282 layout->trailer_padding_size = right_redzone_size - sizeof(BlockTrailer); |
285 layout->trailer_size = sizeof(BlockTrailer); | 283 layout->trailer_size = sizeof(BlockTrailer); |
286 return true; | 284 return true; |
287 } | 285 } |
288 | 286 |
289 void BlockInitialize(const BlockLayout& layout, | 287 void BlockInitialize(const BlockLayout& layout, |
290 void* allocation, | 288 void* allocation, |
291 bool is_nested, | |
292 BlockInfo* block_info) { | 289 BlockInfo* block_info) { |
293 DCHECK_NE(static_cast<void*>(NULL), allocation); | 290 DCHECK_NE(static_cast<void*>(NULL), allocation); |
294 DCHECK(IsAligned(reinterpret_cast<uintptr_t>(allocation), | 291 DCHECK(IsAligned(reinterpret_cast<uintptr_t>(allocation), |
295 layout.block_alignment)); | 292 layout.block_alignment)); |
296 | 293 |
297 // If no output structure is provided then use a local one. We need the data | 294 // If no output structure is provided then use a local one. We need the data |
298 // locally, but the caller might not be interested in it. | 295 // locally, but the caller might not be interested in it. |
299 BlockInfo local_block_info = {}; | 296 BlockInfo local_block_info = {}; |
300 if (block_info == NULL) { | 297 if (block_info == NULL) { |
301 block_info = &local_block_info; | 298 block_info = &local_block_info; |
302 } else { | 299 } else { |
303 ::memset(block_info, 0, sizeof(BlockInfo)); | 300 ::memset(block_info, 0, sizeof(BlockInfo)); |
304 } | 301 } |
305 | 302 |
306 // Get pointers to the various components of the block. | 303 // Get pointers to the various components of the block. |
307 uint8_t* cursor = reinterpret_cast<uint8_t*>(allocation); | 304 uint8_t* cursor = reinterpret_cast<uint8_t*>(allocation); |
308 block_info->block_size = layout.block_size; | 305 block_info->block_size = layout.block_size; |
309 block_info->is_nested = is_nested; | |
310 block_info->header = reinterpret_cast<BlockHeader*>(cursor); | 306 block_info->header = reinterpret_cast<BlockHeader*>(cursor); |
311 cursor += sizeof(BlockHeader); | 307 cursor += sizeof(BlockHeader); |
312 block_info->header_padding = reinterpret_cast<BlockHeaderPadding*>(cursor); | 308 block_info->header_padding = reinterpret_cast<BlockHeaderPadding*>(cursor); |
313 cursor += layout.header_padding_size; | 309 cursor += layout.header_padding_size; |
314 block_info->header_padding_size = layout.header_padding_size; | 310 block_info->header_padding_size = layout.header_padding_size; |
315 block_info->body = reinterpret_cast<BlockBody*>(cursor); | 311 block_info->body = reinterpret_cast<BlockBody*>(cursor); |
316 cursor += layout.body_size; | 312 cursor += layout.body_size; |
317 block_info->body_size = layout.body_size; | 313 block_info->body_size = layout.body_size; |
318 block_info->trailer_padding = reinterpret_cast<BlockTrailerPadding*>(cursor); | 314 block_info->trailer_padding = reinterpret_cast<BlockTrailerPadding*>(cursor); |
319 cursor += layout.trailer_padding_size; | 315 cursor += layout.trailer_padding_size; |
320 block_info->trailer_padding_size = layout.trailer_padding_size; | 316 block_info->trailer_padding_size = layout.trailer_padding_size; |
321 block_info->trailer = reinterpret_cast<BlockTrailer*>(cursor); | 317 block_info->trailer = reinterpret_cast<BlockTrailer*>(cursor); |
322 | 318 |
323 // Indicates if the block is nested. | |
324 block_info->is_nested = is_nested; | |
325 | |
326 // If the block information is being returned to the user then determine | 319 // If the block information is being returned to the user then determine |
327 // the extents of whole pages within it. | 320 // the extents of whole pages within it. |
328 if (block_info != &local_block_info) | 321 if (block_info != &local_block_info) |
329 BlockIdentifyWholePages(block_info); | 322 BlockIdentifyWholePages(block_info); |
330 | 323 |
331 // Initialize the various portions of the memory. The body is not initialized | 324 // Initialize the various portions of the memory. The body is not initialized |
332 // as this is an unnecessary performance hit. | 325 // as this is an unnecessary performance hit. |
333 InitializeBlockHeader(block_info); | 326 InitializeBlockHeader(block_info); |
334 InitializeBlockHeaderPadding(block_info); | 327 InitializeBlockHeaderPadding(block_info); |
335 InitializeBlockTrailerPadding(block_info); | 328 InitializeBlockTrailerPadding(block_info); |
(...skipping 27 matching lines...) Expand all Loading... | |
363 expanded->header_padding = reinterpret_cast<BlockHeaderPadding*>( | 356 expanded->header_padding = reinterpret_cast<BlockHeaderPadding*>( |
364 block + sizeof(BlockHeader)); | 357 block + sizeof(BlockHeader)); |
365 expanded->body = reinterpret_cast<BlockBody*>(block + compact.header_size); | 358 expanded->body = reinterpret_cast<BlockBody*>(block + compact.header_size); |
366 expanded->body_size = compact.block_size - compact.header_size - | 359 expanded->body_size = compact.block_size - compact.header_size - |
367 compact.trailer_size; | 360 compact.trailer_size; |
368 expanded->trailer_padding_size = compact.trailer_size - sizeof(BlockTrailer); | 361 expanded->trailer_padding_size = compact.trailer_size - sizeof(BlockTrailer); |
369 expanded->trailer_padding = reinterpret_cast<BlockTrailerPadding*>( | 362 expanded->trailer_padding = reinterpret_cast<BlockTrailerPadding*>( |
370 block + compact.header_size + expanded->body_size); | 363 block + compact.header_size + expanded->body_size); |
371 expanded->trailer = reinterpret_cast<BlockTrailer*>( | 364 expanded->trailer = reinterpret_cast<BlockTrailer*>( |
372 expanded->RawTrailerPadding() + expanded->trailer_padding_size); | 365 expanded->RawTrailerPadding() + expanded->trailer_padding_size); |
373 expanded->is_nested = compact.is_nested; | |
374 BlockIdentifyWholePages(expanded); | 366 BlockIdentifyWholePages(expanded); |
375 } | 367 } |
376 | 368 |
377 void ConvertBlockInfo(const BlockInfo& expanded, CompactBlockInfo* compact) { | 369 void ConvertBlockInfo(const BlockInfo& expanded, CompactBlockInfo* compact) { |
378 DCHECK_NE(static_cast<CompactBlockInfo*>(nullptr), compact); | 370 DCHECK_NE(static_cast<CompactBlockInfo*>(nullptr), compact); |
379 compact->header = expanded.header; | 371 compact->header = expanded.header; |
380 compact->block_size = expanded.block_size; | 372 compact->block_size = expanded.block_size; |
381 compact->header_size = static_cast<uint32_t>(sizeof(BlockHeader) + | 373 compact->header_size = static_cast<uint32_t>(sizeof(BlockHeader) + |
382 expanded.header_padding_size); | 374 expanded.header_padding_size); |
383 compact->trailer_size = static_cast<uint32_t>(sizeof(BlockTrailer) + | 375 compact->trailer_size = static_cast<uint32_t>(sizeof(BlockTrailer) + |
384 expanded.trailer_padding_size); | 376 expanded.trailer_padding_size); |
385 compact->is_nested = expanded.is_nested; | |
386 } | 377 } |
387 | 378 |
388 bool BlockInfoFromMemory(const BlockHeader* header, BlockInfo* block_info) { | 379 bool BlockInfoFromMemory(const BlockHeader* header, BlockInfo* block_info) { |
389 DCHECK_NE(static_cast<BlockHeader*>(nullptr), header); | 380 DCHECK_NE(static_cast<BlockHeader*>(nullptr), header); |
390 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); | 381 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); |
391 CompactBlockInfo compact = {}; | 382 CompactBlockInfo compact = {}; |
392 if (!BlockInfoFromMemory(header, &compact)) | 383 if (!BlockInfoFromMemory(header, &compact)) |
393 return false; | 384 return false; |
394 ConvertBlockInfo(compact, block_info); | 385 ConvertBlockInfo(compact, block_info); |
395 return true; | 386 return true; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
466 if (block_info.RawBody(i) != kBlockFloodFillByte) | 457 if (block_info.RawBody(i) != kBlockFloodFillByte) |
467 return false; | 458 return false; |
468 } | 459 } |
469 return true; | 460 return true; |
470 } | 461 } |
471 | 462 |
472 // Identifies whole pages in the given block_info. | 463 // Identifies whole pages in the given block_info. |
473 void BlockIdentifyWholePages(BlockInfo* block_info) { | 464 void BlockIdentifyWholePages(BlockInfo* block_info) { |
474 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); | 465 DCHECK_NE(static_cast<BlockInfo*>(NULL), block_info); |
475 static const size_t kPageInfoSize = | 466 static const size_t kPageInfoSize = |
476 FIELD_OFFSET(BlockInfo, is_nested) - | 467 sizeof(BlockInfo) - FIELD_OFFSET(BlockInfo, block_pages); |
Sigurður Ásgeirsson
2016/11/22 19:15:37
I'm not sure this is right - how about field_offse
Sébastien Marchand
2016/11/22 22:12:23
"sizeof(BlockInfo) - FIELD_OFFSET(BlockInfo, block
| |
477 FIELD_OFFSET(BlockInfo, block_pages); | |
478 | 468 |
479 if (block_info->block_size < GetPageSize()) { | 469 if (block_info->block_size < GetPageSize()) { |
480 ::memset(&block_info->block_pages, 0, kPageInfoSize); | 470 ::memset(&block_info->block_pages, 0, kPageInfoSize); |
481 return; | 471 return; |
482 } | 472 } |
483 | 473 |
484 uintptr_t alloc_start = reinterpret_cast<uintptr_t>(block_info->header); | 474 uintptr_t alloc_start = reinterpret_cast<uintptr_t>(block_info->header); |
485 uintptr_t alloc_end = alloc_start + block_info->block_size; | 475 uintptr_t alloc_end = alloc_start + block_info->block_size; |
486 alloc_start = ::common::AlignUp(alloc_start, GetPageSize()); | 476 alloc_start = ::common::AlignUp(alloc_start, GetPageSize()); |
487 alloc_end = ::common::AlignDown(alloc_end, GetPageSize()); | 477 alloc_end = ::common::AlignDown(alloc_end, GetPageSize()); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
739 if (!runtime->HeapIdIsValid(heap_id)) | 729 if (!runtime->HeapIdIsValid(heap_id)) |
740 return false; | 730 return false; |
741 return true; | 731 return true; |
742 } | 732 } |
743 | 733 |
744 bool BlockHeaderIsConsistent(BlockState block_state, | 734 bool BlockHeaderIsConsistent(BlockState block_state, |
745 const BlockInfo& block_info) { | 735 const BlockInfo& block_info) { |
746 const BlockHeader* h = block_info.header; | 736 const BlockHeader* h = block_info.header; |
747 if (h->magic != kBlockHeaderMagic) | 737 if (h->magic != kBlockHeaderMagic) |
748 return false; | 738 return false; |
749 if (static_cast<bool>(h->is_nested) != block_info.is_nested) | |
750 return false; | |
751 | 739 |
752 bool expect_header_padding = block_info.header_padding_size > 0; | 740 bool expect_header_padding = block_info.header_padding_size > 0; |
753 if (static_cast<bool>(h->has_header_padding) != expect_header_padding) | 741 if (static_cast<bool>(h->has_header_padding) != expect_header_padding) |
754 return false; | 742 return false; |
755 | 743 |
756 bool expect_excess_trailer_padding = | 744 bool expect_excess_trailer_padding = |
757 block_info.trailer_padding_size > (kShadowRatio / 2); | 745 block_info.trailer_padding_size > (kShadowRatio / 2); |
758 if (static_cast<bool>(h->has_excess_trailer_padding) != | 746 if (static_cast<bool>(h->has_excess_trailer_padding) != |
759 expect_excess_trailer_padding) { | 747 expect_excess_trailer_padding) { |
760 return false; | 748 return false; |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
943 void SetOnExceptionCallback(OnExceptionCallback callback) { | 931 void SetOnExceptionCallback(OnExceptionCallback callback) { |
944 g_on_exception_callback = callback; | 932 g_on_exception_callback = callback; |
945 } | 933 } |
946 | 934 |
947 void ClearOnExceptionCallback() { | 935 void ClearOnExceptionCallback() { |
948 g_on_exception_callback.Reset(); | 936 g_on_exception_callback.Reset(); |
949 } | 937 } |
950 | 938 |
951 } // namespace asan | 939 } // namespace asan |
952 } // namespace agent | 940 } // namespace agent |
OLD | NEW |