From 4c01c4040a6a1454bf3c32b47953effc429df654 Mon Sep 17 00:00:00 2001 From: "hpayer@chromium.org" Date: Fri, 27 Sep 2013 10:53:07 +0000 Subject: [PATCH] Re-land "Add methods to enable configuration of ResourceConstraints based on limits derived at runtime." Adds ConfigureResourceConstraintsForCurrentPlatform and SetDefaultResourceConstraintsForCurrentPlatform which configure the heap based on the available physical memory, rather than hard-coding by platform as previous. This change also adds OS::TotalPhysicalMemory to platform.h. The re-land fix the performance regression caused by accidental change in default max young space size. BUG=292928 R=hpayer@chromium.org Review URL: https://codereview.chromium.org/24989003 Patch from Ross McIlroy . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16983 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8-defaults.h | 54 +++++++++++++++++++++++++++++++++++++++ include/v8-testing.h | 4 --- include/v8.h | 3 +++ src/d8.cc | 3 +++ src/defaults.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/globals.h | 2 ++ src/heap.cc | 28 ++++++-------------- src/platform-posix.cc | 42 ++++++++++++++++++++++++++++++ src/platform-win32.cc | 12 +++++++++ src/platform.h | 3 +++ tools/gyp/v8.gyp | 1 + 11 files changed, 199 insertions(+), 24 deletions(-) create mode 100644 include/v8-defaults.h create mode 100644 src/defaults.cc diff --git a/include/v8-defaults.h b/include/v8-defaults.h new file mode 100644 index 0000000..381a482 --- /dev/null +++ b/include/v8-defaults.h @@ -0,0 +1,54 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 THE COPYRIGHT +// OWNER 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. + +#ifndef V8_V8_DEFAULTS_H_ +#define V8_V8_DEFAULTS_H_ + +#include "v8.h" + +/** + * Default configuration support for the V8 JavaScript engine. + */ +namespace v8 { + +/** + * Configures the constraints with reasonable default values based on the + * capabilities of the current device the VM is running on. + */ +bool V8_EXPORT ConfigureResourceConstraintsForCurrentPlatform( + ResourceConstraints* constraints); + + +/** + * Convience function which performs SetResourceConstraints with the settings + * returned by ConfigureResourceConstraintsForCurrentPlatform. + */ +bool V8_EXPORT SetDefaultResourceConstraintsForCurrentPlatform(); + +} // namespace v8 + +#endif // V8_V8_DEFAULTS_H_ diff --git a/include/v8-testing.h b/include/v8-testing.h index 97b467a..ba4fcc4 100644 --- a/include/v8-testing.h +++ b/include/v8-testing.h @@ -68,8 +68,4 @@ class V8_EXPORT Testing { } // namespace v8 - -#undef V8_EXPORT - - #endif // V8_V8_TEST_H_ diff --git a/include/v8.h b/include/v8.h index af3c538..70e64a2 100644 --- a/include/v8.h +++ b/include/v8.h @@ -3804,6 +3804,9 @@ class V8_EXPORT ResourceConstraints { }; +/** + * Sets the given ResourceConstraints on the current isolate. + */ bool V8_EXPORT SetResourceConstraints(ResourceConstraints* constraints); diff --git a/src/d8.cc b/src/d8.cc index 614b16e..1c6e453 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -49,6 +49,7 @@ #endif // !V8_SHARED #ifdef V8_SHARED +#include "../include/v8-defaults.h" #include "../include/v8-testing.h" #endif // V8_SHARED @@ -66,6 +67,7 @@ #include "natives.h" #include "platform.h" #include "v8.h" +#include "v8-defaults.h" #endif // V8_SHARED #if !defined(_WIN32) && !defined(_WIN64) @@ -1649,6 +1651,7 @@ int Shell::Main(int argc, char* argv[]) { #else SetStandaloneFlagsViaCommandLine(); #endif + v8::SetDefaultResourceConstraintsForCurrentPlatform(); ShellArrayBufferAllocator array_buffer_allocator; v8::V8::SetArrayBufferAllocator(&array_buffer_allocator); int result = 0; diff --git a/src/defaults.cc b/src/defaults.cc new file mode 100644 index 0000000..301155f --- /dev/null +++ b/src/defaults.cc @@ -0,0 +1,71 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 THE COPYRIGHT +// OWNER 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. + +#include "../include/v8-defaults.h" + +#include "platform.h" +#include "globals.h" +#include "v8.h" + +namespace v8 { + +bool ConfigureResourceConstraintsForCurrentPlatform( + ResourceConstraints* constraints) { + if (constraints == NULL) { + return false; + } + + uint64_t physical_memory = i::OS::TotalPhysicalMemory(); + int lump_of_memory = (i::kPointerSize / 4) * i::MB; + + // The young_space_size should be a power of 2 and old_generation_size should + // be a multiple of Page::kPageSize. + if (physical_memory > 2ul * i::GB) { + constraints->set_max_young_space_size(16 * lump_of_memory); + constraints->set_max_old_space_size(700 * lump_of_memory); + constraints->set_max_executable_size(256 * lump_of_memory); + } else if (physical_memory > 512ul * i::MB) { + constraints->set_max_young_space_size(8 * lump_of_memory); + constraints->set_max_old_space_size(192 * lump_of_memory); + constraints->set_max_executable_size(192 * lump_of_memory); + } else /* (physical_memory <= 512GB) */ { + constraints->set_max_young_space_size(2 * lump_of_memory); + constraints->set_max_old_space_size(96 * lump_of_memory); + constraints->set_max_executable_size(96 * lump_of_memory); + } + return true; +} + + +bool SetDefaultResourceConstraintsForCurrentPlatform() { + ResourceConstraints constraints; + if (!ConfigureResourceConstraintsForCurrentPlatform(&constraints)) + return false; + return SetResourceConstraints(&constraints); +} + +} // namespace v8::internal diff --git a/src/globals.h b/src/globals.h index 1977e68..d06c6d7 100644 --- a/src/globals.h +++ b/src/globals.h @@ -248,10 +248,12 @@ const int kRandomStateSize = 2 * kIntSize; const int kPointerSizeLog2 = 3; const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF); +const bool kIs64BitArch = true; #else const int kPointerSizeLog2 = 2; const intptr_t kIntptrSignBit = 0x80000000; const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu; +const bool kIs64BitArch = false; #endif const int kBitsPerByte = 8; diff --git a/src/heap.cc b/src/heap.cc index 6e9a295..5d75cb4 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -67,29 +67,14 @@ namespace internal { Heap::Heap() : isolate_(NULL), + code_range_size_(kIs64BitArch ? 512 * MB : 0), // semispace_size_ should be a power of 2 and old_generation_size_ should be // a multiple of Page::kPageSize. -#if V8_TARGET_ARCH_X64 -#define LUMP_OF_MEMORY (2 * MB) - code_range_size_(512*MB), -#else -#define LUMP_OF_MEMORY MB - code_range_size_(0), -#endif -#if defined(ANDROID) || V8_TARGET_ARCH_MIPS - reserved_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)), - max_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)), - initial_semispace_size_(Page::kPageSize), - max_old_generation_size_(192*MB), - max_executable_size_(max_old_generation_size_), -#else - reserved_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)), - max_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)), + reserved_semispace_size_(8 * (kPointerSize / 4) * MB), + max_semispace_size_(8 * (kPointerSize / 4) * MB), initial_semispace_size_(Page::kPageSize), - max_old_generation_size_(700ul * LUMP_OF_MEMORY), - max_executable_size_(256l * LUMP_OF_MEMORY), -#endif - + max_old_generation_size_(700ul * (kPointerSize / 4) * MB), + max_executable_size_(256ul * (kPointerSize / 4) * MB), // Variables set based on semispace_size_ and old_generation_size_ in // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) // Will be 4 * reserved_semispace_size_ to ensure that young @@ -170,6 +155,9 @@ Heap::Heap() max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; #endif + // Ensure old_generation_size_ is a multiple of kPageSize. + ASSERT(MB >= Page::kPageSize); + intptr_t max_virtual = OS::MaxVirtualMemory(); if (max_virtual > 0) { diff --git a/src/platform-posix.cc b/src/platform-posix.cc index df15ee2..797557d 100644 --- a/src/platform-posix.cc +++ b/src/platform-posix.cc @@ -100,6 +100,48 @@ intptr_t OS::MaxVirtualMemory() { } +uint64_t OS::TotalPhysicalMemory() { +#if V8_OS_MACOSX + int mib[2]; + mib[0] = CTL_HW; + mib[1] = HW_MEMSIZE; + int64_t size = 0; + size_t len = sizeof(size); + if (sysctl(mib, 2, &size, &len, NULL, 0) != 0) { + UNREACHABLE(); + return 0; + } + return static_cast(size); +#elif V8_OS_FREEBSD + int pages, page_size; + size_t size = sizeof(pages); + sysctlbyname("vm.stats.vm.v_page_count", &pages, &size, NULL, 0); + sysctlbyname("vm.stats.vm.v_page_size", &page_size, &size, NULL, 0); + if (pages == -1 || page_size == -1) { + UNREACHABLE(); + return 0; + } + return static_cast(pages) * page_size; +#elif V8_OS_CYGWIN + MEMORYSTATUS memory_info; + memory_info.dwLength = sizeof(memory_info); + if (!GlobalMemoryStatus(&memory_info)) { + UNREACHABLE(); + return 0; + } + return static_cast(memory_info.dwTotalPhys); +#else + intptr_t pages = sysconf(_SC_PHYS_PAGES); + intptr_t page_size = sysconf(_SC_PAGESIZE); + if (pages == -1 || page_size == -1) { + UNREACHABLE(); + return 0; + } + return static_cast(pages) * page_size; +#endif +} + + int OS::ActivationFrameAlignment() { #if V8_TARGET_ARCH_ARM // On EABI ARM targets this is required for fp correctness in the diff --git a/src/platform-win32.cc b/src/platform-win32.cc index 41a4f14..3283dfa 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -1271,6 +1271,18 @@ void OS::SignalCodeMovingGC() { } +uint64_t OS::TotalPhysicalMemory() { + MEMORYSTATUSEX memory_info; + memory_info.dwLength = sizeof(memory_info); + if (!GlobalMemoryStatusEx(&memory_info)) { + UNREACHABLE(); + return 0; + } + + return static_cast(memory_info.ullTotalPhys); +} + + #else // __MINGW32__ void OS::LogSharedLibraryAddresses(Isolate* isolate) { } void OS::SignalCodeMovingGC() { } diff --git a/src/platform.h b/src/platform.h index 527de16..8e524ae 100644 --- a/src/platform.h +++ b/src/platform.h @@ -302,6 +302,9 @@ class OS { // positions indicated by the members of the CpuFeature enum from globals.h static uint64_t CpuFeaturesImpliedByPlatform(); + // The total amount of physical memory available on the current system. + static uint64_t TotalPhysicalMemory(); + // Maximum size of the virtual memory. 0 means there is no artificial // limit. static intptr_t MaxVirtualMemory(); diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index 8a75a09..94c79fb 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -270,6 +270,7 @@ '../../src/debug-agent.h', '../../src/debug.cc', '../../src/debug.h', + '../../src/defaults.cc', '../../src/deoptimizer.cc', '../../src/deoptimizer.h', '../../src/disasm.h', -- 2.7.4