Chromium Code Reviews| 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 |