1/* 2 * Copyright (c) 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20// 21// slop.m 22// Copyright (c) 2009-2011 Apple Inc. All rights reserved. 23// 24 25#import "BlackBoxTest.h" 26#import <objc/runtime.h> 27 28@interface SlopTester : TestFinalizer 29@end 30 31@implementation SlopTester 32- (id)init 33{ 34 self = [super init]; 35 if (self) { 36 size_t mySize = malloc_size(self); 37 size_t instanceSize = class_getInstanceSize([self class]); 38 char *slopPtr = (char *)self; 39 for (size_t slopIndex = instanceSize; slopIndex < mySize; slopIndex++) { 40 if (slopPtr[slopIndex]) 41 [[TestCase currentTestCase] fail:@"detected nonzero byte in slop area"]; 42 } 43 44 // store some nonzero bytes in the slop for the next iteration to check 45 for (size_t slopIndex = instanceSize; slopIndex < mySize; slopIndex++) { 46 slopPtr[slopIndex] = 0xff; 47 } 48 } 49 return self; 50} 51@end 52 53 54@interface Slop : BlackBoxTest 55{ 56 int _iterations; 57 int _blockCount; 58 int _reusedCount; 59 NSHashTable *_usedBlocks; 60} 61- (void)iterate; 62@end 63 64@implementation Slop 65 66#define EXTRA_SIZE_MAX 1024 67#define MIN_ITERATIONS 5 68 69- (void)checkResult 70{ 71 if (_blockCount > 0) { 72 [self fail:[NSString stringWithFormat:@"did not collect %d test blocks", _blockCount]]; 73 } else { 74 if (_reusedCount < EXTRA_SIZE_MAX || _iterations < MIN_ITERATIONS) { 75 [self iterate]; 76 return; 77 } 78 } 79 if (_reusedCount == 0) { 80 [self fail:@"did not reuse any blocks - slop may not be checked"]; 81 } 82 [self passed]; 83 [self testFinished]; 84 _usedBlocks = nil; 85} 86 87- (void)allocate 88{ 89 @synchronized(self) { 90 Class st = [SlopTester class]; 91 for (size_t extra = 0; extra < EXTRA_SIZE_MAX; extra++) { 92 id o = [NSAllocateObject(st, extra, NULL) init]; 93 if ([_usedBlocks member:(id)[self disguise:o]]) 94 _reusedCount++; 95 else 96 [_usedBlocks addObject:(id)[self disguise:o]]; 97 _blockCount++; 98 } 99 } 100} 101 102- (void)iterate 103{ 104 _iterations++; 105 [self allocate]; 106 [self clearStack]; 107 [self runThreadLocalCollection]; 108 [self requestFullCollectionWithCompletionCallback:^{ [self checkResult]; }]; 109} 110 111- (void)performTest 112{ 113 _usedBlocks = [NSHashTable hashTableWithOptions:NSPointerFunctionsOpaquePersonality]; 114 [self iterate]; 115} 116 117- (void)didFinalize:(TestFinalizer *)finalizer 118{ 119 @synchronized(self) { 120 _blockCount--; 121 } 122} 123 124@end 125