Changeset 187125 in webkit
- Timestamp:
- Jul 21, 2015 2:41:30 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r187119 r187125 1 2015-07-21 Filip Pizlo <fpizlo@apple.com> 2 3 Fixed VM pool allocation should have a reserve for allocations that cannot fail 4 https://bugs.webkit.org/show_bug.cgi?id=147154 5 rdar://problem/21847618 6 7 Reviewed by Geoffrey Garen. 8 9 This adds the notion of a JIT pool reserve fraction. Some fraction, currently 1/4, of 10 the JIT pool is reserved for allocations that cannot fail. It makes sense to make this 11 a fraction rather than a constant because each allocation that can fail may cause some 12 number of allocations that cannot fail (for example, the OSR exit thunks that we 13 compile when we exit from some CodeBlock cannot fail). 14 15 I've tested this by adding a test mode where we artificially limit the JIT pool size. 16 Prior to the fix, we had >20 failures. Now we have none. 17 18 * heap/GCLogging.cpp: 19 (WTF::printInternal): I needed a dump method on Options members when debugging this. 20 * heap/GCLogging.h: 21 * jit/ExecutableAllocator.h: Raise the ARM64 limit to 32MB because 16MB is cutting it too close. 22 * jit/ExecutableAllocatorFixedVMPool.cpp: 23 (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): Add the ability to artificially limit JIT pool size for testing. 24 (JSC::ExecutableAllocator::memoryPressureMultiplier): Implement the reserve when computing memory pressure for JIT tier-up heuristics. 25 (JSC::ExecutableAllocator::allocate): Implement the reserve when allocating can-fail things. 26 * jsc.cpp: Rewire some options parsing so that CommandLine happens before we create the JIT pool. 27 (main): 28 (CommandLine::parseArguments): 29 (jscmain): 30 * runtime/Options.cpp: 31 (JSC::OptionRange::dump): I needed a dump method on Options members when debugging this. 32 (JSC::Options::initialize): This can now be called more than once. 33 * runtime/Options.h: 34 1 35 2015-07-21 Saam barati <saambarati1@gmail.com> 2 36 -
trunk/Source/JavaScriptCore/heap/GCLogging.cpp
r183124 r187125 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "JSCell.h" 33 33 #include "JSCellInlines.h" 34 #include <wtf/PrintStream.h> 34 35 35 36 namespace JSC { … … 114 115 115 116 } // namespace JSC 117 118 namespace WTF { 119 120 void printInternal(PrintStream& out, JSC::GCLogging::Level level) 121 { 122 switch (level) { 123 case JSC::GCLogging::Level::None: 124 out.print("None"); 125 return; 126 case JSC::GCLogging::Level::Basic: 127 out.print("Basic"); 128 return; 129 case JSC::GCLogging::Level::Verbose: 130 out.print("Verbose"); 131 return; 132 default: 133 out.print("Level=", level - JSC::GCLogging::Level::None); 134 return; 135 } 136 } 137 138 } // namespace WTF 139 -
trunk/Source/JavaScriptCore/heap/GCLogging.h
r166838 r187125 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 49 49 } // namespace JSC 50 50 51 namespace WTF { 52 53 class PrintStream; 54 55 void printInternal(PrintStream&, JSC::GCLogging::Level); 56 57 } // namespace WTF 58 51 59 #endif // GCLogging_h -
trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h
r185532 r187125 81 81 82 82 #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) 83 #if CPU(ARM) || CPU(ARM64)83 #if CPU(ARM) 84 84 static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024; 85 #elif CPU(ARM64) 86 static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024; 85 87 #elif CPU(X86_64) 86 88 static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024; … … 88 90 static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024; 89 91 #endif 92 static const double executablePoolReservationFraction = 0.25; 90 93 91 94 extern uintptr_t startOfFixedExecutableMemoryPool; -
trunk/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
r185532 r187125 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 61 61 : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes 62 62 { 63 m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true); 63 size_t reservationSize; 64 if (Options::jitMemoryReservationSize()) 65 reservationSize = Options::jitMemoryReservationSize(); 66 else 67 reservationSize = fixedExecutableMemoryPoolSize; 68 m_reservation = PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true); 64 69 if (m_reservation) { 65 ASSERT(m_reservation.size() == fixedExecutableMemoryPoolSize);70 ASSERT(m_reservation.size() == reservationSize); 66 71 addFreshFreeSpace(m_reservation.base(), m_reservation.size()); 67 72 … … 149 154 ASSERT(statistics.bytesAllocated <= statistics.bytesReserved); 150 155 size_t bytesAllocated = statistics.bytesAllocated + addedMemoryUsage; 151 if (bytesAllocated >= statistics.bytesReserved) 152 bytesAllocated = statistics.bytesReserved; 156 size_t bytesAvailable = static_cast<size_t>( 157 statistics.bytesReserved * (1 - executablePoolReservationFraction)); 158 if (bytesAllocated >= bytesAvailable) 159 bytesAllocated = bytesAvailable; 153 160 double result = 1.0; 154 size_t divisor = statistics.bytesReserved- bytesAllocated;161 size_t divisor = bytesAvailable - bytesAllocated; 155 162 if (divisor) 156 result = static_cast<double>( statistics.bytesReserved) / divisor;163 result = static_cast<double>(bytesAvailable) / divisor; 157 164 if (result < 1.0) 158 165 result = 1.0; … … 170 177 && doExecutableAllocationFuzzingIfEnabled() == PretendToFailExecutableAllocation) 171 178 return nullptr; 179 180 if (effort == JITCompilationCanFail) { 181 // Don't allow allocations if we are down to reserve. 182 MetaAllocator::Statistics statistics = allocator->currentStatistics(); 183 size_t bytesAllocated = statistics.bytesAllocated + sizeInBytes; 184 size_t bytesAvailable = static_cast<size_t>( 185 statistics.bytesReserved * (1 - executablePoolReservationFraction)); 186 if (bytesAllocated > bytesAvailable) 187 return nullptr; 188 } 172 189 173 190 RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID); -
trunk/Source/JavaScriptCore/jsc.cpp
r186966 r187125 1249 1249 #endif 1250 1250 1251 // Initialize JSC before getting VM.1252 #if ENABLE(SAMPLING_REGIONS)1253 WTF::initializeMainThread();1254 #endif1255 JSC::initializeThreading();1256 1257 1251 if (char* timeoutString = getenv("JSC_timeout")) { 1258 1252 if (sscanf(timeoutString, "%lf", &s_desiredTimeout) != 1) { … … 1431 1425 void CommandLine::parseArguments(int argc, char** argv) 1432 1426 { 1427 Options::initialize(); 1428 1433 1429 int i = 1; 1434 1430 bool needToDumpOptions = false; … … 1495 1491 1496 1492 // See if the -- option is a JSC VM option. 1497 // NOTE: At this point, we know that the arg starts with "--". Skip it. 1498 if (JSC::Options::setOption(&arg[2])) { 1493 if (strstr(arg, "--") == arg && JSC::Options::setOption(&arg[2])) { 1499 1494 // The arg was recognized as a VM option and has been parsed. 1500 1495 continue; // Just continue with the next arg. … … 1524 1519 // comes first. 1525 1520 CommandLine options(argc, argv); 1521 1522 // Initialize JSC before getting VM. 1523 #if ENABLE(SAMPLING_REGIONS) 1524 WTF::initializeMainThread(); 1525 #endif 1526 JSC::initializeThreading(); 1527 1526 1528 VM* vm = &VM::create(LargeHeap).leakRef(); 1527 1529 int result; -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r186688 r187125 31 31 #include <limits> 32 32 #include <math.h> 33 #include <mutex> 33 34 #include <stdlib.h> 34 35 #include <string.h> … … 200 201 201 202 return m_state == Normal ? false : true; 203 } 204 205 void OptionRange::dump(PrintStream& out) const 206 { 207 out.print(m_rangeString); 202 208 } 203 209 … … 319 325 void Options::initialize() 320 326 { 321 // Initialize each of the options with their default values: 322 #define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \ 323 name_() = defaultValue_; \ 324 name_##Default() = defaultValue_; 325 JSC_OPTIONS(FOR_EACH_OPTION) 327 static std::once_flag initializeOptionsOnceFlag; 328 329 std::call_once( 330 initializeOptionsOnceFlag, 331 [] { 332 // Initialize each of the options with their default values: 333 #define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \ 334 name_() = defaultValue_; \ 335 name_##Default() = defaultValue_; 336 JSC_OPTIONS(FOR_EACH_OPTION) 326 337 #undef FOR_EACH_OPTION 327 338 328 // It *probably* makes sense for other platforms to enable this.339 // It *probably* makes sense for other platforms to enable this. 329 340 #if PLATFORM(IOS) && CPU(ARM64) 330 enableLLVMFastISel() = true;341 enableLLVMFastISel() = true; 331 342 #endif 332 343 333 // Allow environment vars to override options if applicable.334 // The evn var should be the name of the option prefixed with335 // "JSC_".336 #define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \337 overrideOptionWithHeuristic(name_(), "JSC_" #name_);338 JSC_OPTIONS(FOR_EACH_OPTION)344 // Allow environment vars to override options if applicable. 345 // The evn var should be the name of the option prefixed with 346 // "JSC_". 347 #define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \ 348 overrideOptionWithHeuristic(name_(), "JSC_" #name_); 349 JSC_OPTIONS(FOR_EACH_OPTION) 339 350 #undef FOR_EACH_OPTION 340 351 341 352 #if 0 342 ; // Deconfuse editors that do auto indentation353 ; // Deconfuse editors that do auto indentation 343 354 #endif 344 355 345 recomputeDependentOptions(); 346 347 // Do range checks where needed and make corrections to the options: 348 ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp()); 349 ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon()); 350 ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0); 351 352 if (Options::showOptions()) { 353 DumpLevel level = static_cast<DumpLevel>(Options::showOptions()); 354 if (level > DumpLevel::Verbose) 355 level = DumpLevel::Verbose; 356 357 const char* title = nullptr; 358 switch (level) { 359 case DumpLevel::None: 360 break; 361 case DumpLevel::Overridden: 362 title = "Overridden JSC options:"; 363 break; 364 case DumpLevel::All: 365 title = "All JSC options:"; 366 break; 367 case DumpLevel::Verbose: 368 title = "All JSC options with descriptions:"; 369 break; 370 } 371 dumpAllOptions(level, title); 372 } 373 374 ensureOptionsAreCoherent(); 356 recomputeDependentOptions(); 357 358 // Do range checks where needed and make corrections to the options: 359 ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp()); 360 ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon()); 361 ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0); 362 363 if (Options::showOptions()) { 364 DumpLevel level = static_cast<DumpLevel>(Options::showOptions()); 365 if (level > DumpLevel::Verbose) 366 level = DumpLevel::Verbose; 367 368 const char* title = nullptr; 369 switch (level) { 370 case DumpLevel::None: 371 break; 372 case DumpLevel::Overridden: 373 title = "Overridden JSC options:"; 374 break; 375 case DumpLevel::All: 376 title = "All JSC options:"; 377 break; 378 case DumpLevel::Verbose: 379 title = "All JSC options with descriptions:"; 380 break; 381 } 382 dumpAllOptions(level, title); 383 } 384 385 ensureOptionsAreCoherent(); 386 }); 375 387 } 376 388 -
trunk/Source/JavaScriptCore/runtime/Options.h
r186701 r187125 31 31 #include <stdint.h> 32 32 #include <stdio.h> 33 #include <wtf/PrintStream.h> 33 34 #include <wtf/StdLibExtras.h> 34 35 … … 81 82 bool isInRange(unsigned); 82 83 const char* rangeString() const { return (m_state > InitError) ? m_rangeString : "<null>"; } 84 85 void dump(PrintStream& out) const; 83 86 84 87 private: … … 107 110 \ 108 111 v(bool, crashIfCantAllocateJITMemory, false, nullptr) \ 112 v(unsigned, jitMemoryReservationSize, 0, nullptr) \ 109 113 \ 110 114 v(bool, forceDFGCodeBlockLiveness, false, nullptr) \ … … 351 355 }; 352 356 353 static void initialize();357 JS_EXPORT_PRIVATE static void initialize(); 354 358 355 359 // Parses a single command line option in the format "<optionName>=<value>" -
trunk/Tools/ChangeLog
r187100 r187125 1 2015-07-21 Filip Pizlo <fpizlo@apple.com> 2 3 Fixed VM pool allocation should have a reserve for allocations that cannot fail 4 https://bugs.webkit.org/show_bug.cgi?id=147154 5 rdar://problem/21847618 6 7 Reviewed by Geoffrey Garen. 8 9 Add a new test mode where we artificially limit JIT memory to 50KB. If our JIT OOM 10 mitigations work, these should all pass. Prior to this patch there were >20 failures. 11 12 * Scripts/run-jsc-stress-tests: 13 1 14 2015-07-20 Carlos Garcia Campos <cgarcia@igalia.com> 2 15 -
trunk/Tools/Scripts/run-jsc-stress-tests
r185833 r187125 759 759 end 760 760 761 def runFTLNoCJITSmallPool 762 run("ftl-no-cjit-small-pool", "--jitMemoryReservationSize=50000", *(FTL_OPTIONS + NO_CJIT_OPTIONS)) if $enableFTL 763 end 764 761 765 def defaultRun 762 766 runDefault … … 772 776 runFTLEager 773 777 runFTLEagerNoCJITValidate 778 runFTLNoCJITSmallPool 774 779 end 775 780 end
Note: See TracChangeset
for help on using the changeset viewer.