From 767a5c606262f54fb66da72924d811b0977e29dc Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 11 Apr 2015 19:37:48 +0200 Subject: [PATCH] deps: upgrade v8 to 4.2.77.15 This includes the out-of-tree patch (but fixed in upstream HEAD) from commit 41c00a2 ("deps: enable v8 postmortem debugging again".) PR-URL: https://github.com/iojs/io.js/pull/1399 Reviewed-By: Fedor Indutny --- deps/v8/include/v8-version.h | 2 +- deps/v8/src/api-natives.cc | 46 ++++++++++------------ deps/v8/src/api-natives.h | 2 + deps/v8/src/bootstrapper.cc | 4 +- deps/v8/src/contexts.h | 2 +- deps/v8/src/type-info.cc | 3 ++ deps/v8/test/cctest/test-api.cc | 16 ++++---- deps/v8/tools/testrunner/local/progress.py | 18 +++++++++ 8 files changed, 57 insertions(+), 36 deletions(-) diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 49f41f05073126..c5318ac604e6a3 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 4 #define V8_MINOR_VERSION 2 #define V8_BUILD_NUMBER 77 -#define V8_PATCH_LEVEL 13 +#define V8_PATCH_LEVEL 15 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/api-natives.cc b/deps/v8/src/api-natives.cc index ed434caa004e73..11f20efe862d87 100644 --- a/deps/v8/src/api-natives.cc +++ b/deps/v8/src/api-natives.cc @@ -207,36 +207,33 @@ MaybeHandle InstantiateObject(Isolate* isolate, } -void InstallInCache(Isolate* isolate, int serial_number, - Handle function) { +void CacheFunction(Isolate* isolate, Handle serial_number, + Handle function) { auto cache = isolate->function_cache(); - if (cache->length() <= serial_number) { - int new_size; - if (isolate->next_serial_number() < 50) { - new_size = 100; - } else { - new_size = 3 * isolate->next_serial_number() / 2; - } - cache = FixedArray::CopySize(cache, new_size); - isolate->native_context()->set_function_cache(*cache); - } - cache->set(serial_number, *function); + auto new_cache = ObjectHashTable::Put(cache, serial_number, function); + isolate->native_context()->set_function_cache(*new_cache); +} + + +void UncacheFunction(Isolate* isolate, Handle serial_number) { + auto cache = isolate->function_cache(); + bool was_present = false; + auto new_cache = ObjectHashTable::Remove(cache, serial_number, &was_present); + DCHECK(was_present); + isolate->native_context()->set_function_cache(*new_cache); } MaybeHandle InstantiateFunction(Isolate* isolate, Handle data, Handle name) { - int serial_number = Smi::cast(data->serial_number())->value(); + auto serial_number = handle(Smi::cast(data->serial_number()), isolate); // Probe cache. if (!data->do_not_cache()) { auto cache = isolate->function_cache(); - // Fast case: see if the function has already been instantiated - if (serial_number < cache->length()) { - Handle element = FixedArray::get(cache, serial_number); - if (element->IsJSFunction()) { - return Handle::cast(element); - } + Object* element = cache->Lookup(serial_number); + if (element->IsJSFunction()) { + return handle(JSFunction::cast(element), isolate); } } // Enter a new scope. Recursion could otherwise create a lot of handles. @@ -279,15 +276,14 @@ MaybeHandle InstantiateFunction(Isolate* isolate, function->shared()->set_name(*name); } if (!data->do_not_cache()) { - // Cache the function to limit recursion. - InstallInCache(isolate, serial_number, function); + // Cache the function. + CacheFunction(isolate, serial_number, function); } auto result = ConfigureInstance(isolate, function, data); if (result.is_null()) { - // uncache on error. + // Uncache on error. if (!data->do_not_cache()) { - auto cache = isolate->function_cache(); - cache->set(serial_number, isolate->heap()->undefined_value()); + UncacheFunction(isolate, serial_number); } return MaybeHandle(); } diff --git a/deps/v8/src/api-natives.h b/deps/v8/src/api-natives.h index 9f97b5d018fc6a..224c78a6adb421 100644 --- a/deps/v8/src/api-natives.h +++ b/deps/v8/src/api-natives.h @@ -12,6 +12,8 @@ namespace internal { class ApiNatives { public: + static const int kInitialFunctionCacheSize = 256; + MUST_USE_RESULT static MaybeHandle InstantiateFunction( Handle data); diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 31d6e3e00c2cc3..2592bb733008d3 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -2059,7 +2059,9 @@ bool Genesis::InstallNatives() { InstallNativeFunctions(); - native_context()->set_function_cache(heap()->empty_fixed_array()); + auto function_cache = + ObjectHashTable::New(isolate(), ApiNatives::kInitialFunctionCacheSize); + native_context()->set_function_cache(*function_cache); // Store the map for the string prototype after the natives has been compiled // and the String function has been set up. diff --git a/deps/v8/src/contexts.h b/deps/v8/src/contexts.h index f932c60092dcba..3d34e0ec77a6ce 100644 --- a/deps/v8/src/contexts.h +++ b/deps/v8/src/contexts.h @@ -138,7 +138,7 @@ enum BindingFlags { V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \ V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \ V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun) \ - V(FUNCTION_CACHE_INDEX, FixedArray, function_cache) \ + V(FUNCTION_CACHE_INDEX, ObjectHashTable, function_cache) \ V(JSFUNCTION_RESULT_CACHES_INDEX, FixedArray, jsfunction_result_caches) \ V(NORMALIZED_MAP_CACHE_INDEX, Object, normalized_map_cache) \ V(RUNTIME_CONTEXT_INDEX, Context, runtime_context) \ diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc index 01943414a7cb60..96bd0ed0e3ae4a 100644 --- a/deps/v8/src/type-info.cc +++ b/deps/v8/src/type-info.cc @@ -437,6 +437,9 @@ bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, } constructor = map->constructor(); if (constructor->IsNull()) return false; + // If the constructor is not null or a JSFunction, we have to conservatively + // assume that it may retain a native context. + if (!constructor->IsJSFunction()) return true; JSFunction* function = JSFunction::cast(constructor); return CanRetainOtherContext(function, native_context); } diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index adc7c092169393..04b573a108a6b1 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -20335,15 +20335,15 @@ THREADED_TEST(FunctionNew) { env->Global()->Set(v8_str("func"), func); Local result = CompileRun("func();"); CHECK(v8::Integer::New(isolate, 17)->Equals(result)); - // Verify function not cached - int serial_number = - i::Smi::cast(v8::Utils::OpenHandle(*func) - ->shared()->get_api_func_data()->serial_number())->value(); i::Isolate* i_isolate = reinterpret_cast(isolate); - i::Handle cache(i_isolate->native_context()->function_cache()); - if (serial_number < cache->length()) { - CHECK(cache->get(serial_number)->IsUndefined()); - } + // Verify function not cached + auto serial_number = handle(i::Smi::cast(v8::Utils::OpenHandle(*func) + ->shared() + ->get_api_func_data() + ->serial_number()), + i_isolate); + auto cache = i_isolate->function_cache(); + CHECK(cache->Lookup(serial_number)->IsTheHole()); // Verify that each Function::New creates a new function instance Local data2 = v8::Object::New(isolate); function_new_expected_env = data2; diff --git a/deps/v8/tools/testrunner/local/progress.py b/deps/v8/tools/testrunner/local/progress.py index 2616958c47887f..ed9d315b4ed36e 100644 --- a/deps/v8/tools/testrunner/local/progress.py +++ b/deps/v8/tools/testrunner/local/progress.py @@ -291,6 +291,7 @@ def __init__(self, progress_indicator, json_test_results, arch, mode): self.arch = arch self.mode = mode self.results = [] + self.tests = [] def Starting(self): self.progress_indicator.runner = self.runner @@ -304,10 +305,24 @@ def Done(self): # Buildbot might start out with an empty file. complete_results = json.loads(f.read() or "[]") + # Sort tests by duration. + timed_tests = [t for t in self.tests if t.duration is not None] + timed_tests.sort(lambda a, b: cmp(b.duration, a.duration)) + slowest_tests = [ + { + "name": test.GetLabel(), + "flags": test.flags, + "command": EscapeCommand(self.runner.GetCommand(test)).replace( + ABS_PATH_PREFIX, ""), + "duration": test.duration, + } for test in timed_tests[:20] + ] + complete_results.append({ "arch": self.arch, "mode": self.mode, "results": self.results, + "slowest_tests": slowest_tests, }) with open(self.json_test_results, "w") as f: @@ -318,6 +333,8 @@ def AboutToRun(self, test): def HasRun(self, test, has_unexpected_output): self.progress_indicator.HasRun(test, has_unexpected_output) + # Buffer all tests for sorting the durations in the end. + self.tests.append(test) if not has_unexpected_output: # Omit tests that run as expected. Passing tests of reruns after failures # will have unexpected_output to be reported here has well. @@ -334,6 +351,7 @@ def HasRun(self, test, has_unexpected_output): "exit_code": test.output.exit_code, "result": test.suite.GetOutcome(test), "expected": list(test.outcomes or ["PASS"]), + "duration": test.duration, })