/* * Copyright (C) 2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import <JavaScriptCore/JavaScriptCore.h> #import <inttypes.h> #import <stdio.h> #if __has_include(<libproc.h>) #define HAS_LIBPROC 1 #import <libproc.h> #else #define HAS_LIBPROC 0 #endif #if HAS_LIBPROC && RUSAGE_INFO_CURRENT >= 4 && JSC_OBJC_API_ENABLED static void description() { printf("usage \n testmem <path-to-file-to-run> [iterations]\n"); } struct Footprint { uint64_t current; uint64_t peak; static Footprint now() { rusage_info_v4 rusage; if (proc_pid_rusage(getpid(), RUSAGE_INFO_V4, (rusage_info_t *)&rusage)) { printf("Failure when calling rusage\n"); exit(1); } return { rusage.ri_phys_footprint, rusage.ri_lifetime_max_phys_footprint }; } }; int main(int argc, char* argv[]) { if (argc < 2) { description(); exit(1); } size_t iterations = 20; if (argc >= 3) { int iters = atoi(argv[2]); if (iters < 0) { printf("Iterations argument must be >= 0"); exit(1); } iterations = iters; } NSString *path = [NSString stringWithUTF8String:argv[1]]; NSString *script = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; if (!script) { printf("Can't open file: %s\n", argv[1]); exit(1); } auto startTime = CFAbsoluteTimeGetCurrent(); JSVirtualMachine* vm = [[JSVirtualMachine alloc] init]; for (size_t i = 0; i < iterations; ++i) { @autoreleasepool { JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm]; context.exceptionHandler = ^(JSContext*, JSValue*) { printf("Unexpected exception thrown\n"); exit(1); }; [context evaluateScript:script]; } } auto time = CFAbsoluteTimeGetCurrent() - startTime; auto footprint = Footprint::now(); printf("time: %lf\n", time); // Seconds printf("peak footprint: %" PRIu64 "\n", footprint.peak); // Bytes printf("footprint at end: %" PRIu64 "\n", footprint.current); // Bytes return 0; } #else int main(int, char*[]) { printf("You need to compile this file with an SDK that has RUSAGE_INFO_V4 or later\n"); return 1; } #endif