Skip to content

Commit

Permalink
Version 4.2.77.14 (cherry-pick)
Browse files Browse the repository at this point in the history
Merged d7f25f5

use a hash table for the function cache as blink is leaking functiontemplates

[email protected]
BUG=472608

Review URL: https://codereview.chromium.org/1053973002

Cr-Commit-Position: refs/branch-heads/4.2@{#16}
Cr-Branched-From: 3dfd929-refs/heads/4.2.77@{#2}
Cr-Branched-From: e011092-refs/heads/master@{#26757}
  • Loading branch information
Dan Carney committed Apr 2, 2015
1 parent 4995dac commit e65bd3e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 36 deletions.
2 changes: 1 addition & 1 deletion include/v8-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 14

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
46 changes: 21 additions & 25 deletions src/api-natives.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,36 +207,33 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
}


void InstallInCache(Isolate* isolate, int serial_number,
Handle<JSFunction> function) {
void CacheFunction(Isolate* isolate, Handle<Smi> serial_number,
Handle<JSFunction> 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<Smi> 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<JSFunction> InstantiateFunction(Isolate* isolate,
Handle<FunctionTemplateInfo> data,
Handle<Name> 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<Object> element = FixedArray::get(cache, serial_number);
if (element->IsJSFunction()) {
return Handle<JSFunction>::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.
Expand Down Expand Up @@ -279,15 +276,14 @@ MaybeHandle<JSFunction> 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<JSFunction>();
}
Expand Down
2 changes: 2 additions & 0 deletions src/api-natives.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace internal {

class ApiNatives {
public:
static const int kInitialFunctionCacheSize = 256;

MUST_USE_RESULT static MaybeHandle<JSFunction> InstantiateFunction(
Handle<FunctionTemplateInfo> data);

Expand Down
4 changes: 3 additions & 1 deletion src/bootstrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
16 changes: 8 additions & 8 deletions test/cctest/test-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20335,15 +20335,15 @@ THREADED_TEST(FunctionNew) {
env->Global()->Set(v8_str("func"), func);
Local<Value> 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<i::Isolate*>(isolate);
i::Handle<i::FixedArray> 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<Object> data2 = v8::Object::New(isolate);
function_new_expected_env = data2;
Expand Down

0 comments on commit e65bd3e

Please sign in to comment.