Commit 00ba7116 authored by jochen@chromium.org's avatar jochen@chromium.org

Use a per-isolate cache for the date object JS bits

The old per-context cache made it difficult for the embedder to notify
v8 of date/time configuration changes. The embedder had to enter all
contexts for the isolate and notify v8 for each context.

With the new per-isolate cache, the embedder only needs to notify v8
once per isolate.

BUG=348856
LOG=y
R=dcarney@chromium.org, ulan@chromium.org
TEST=cctest/test-date

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19784 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 91a2aa6a
......@@ -5618,30 +5618,17 @@ void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
i_isolate->date_cache()->ResetDateCache();
i::HandleScope scope(i_isolate);
// Get the function ResetDateCache (defined in date.js).
i::Handle<i::String> func_name_str =
i_isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("ResetDateCache"));
i::MaybeObject* result =
i_isolate->js_builtins_object()->GetProperty(*func_name_str);
i::Object* object_func;
if (!result->ToObject(&object_func)) {
if (!i_isolate->eternal_handles()->Exists(
i::EternalHandles::DATE_CACHE_VERSION)) {
return;
}
if (object_func->IsJSFunction()) {
i::Handle<i::JSFunction> func =
i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
// Call ResetDateCache(0 but expect no exceptions:
bool caught_exception = false;
i::Execution::TryCall(func,
i_isolate->js_builtins_object(),
0,
NULL,
&caught_exception);
}
i::Handle<i::FixedArray> date_cache_version =
i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
i::EternalHandles::DATE_CACHE_VERSION));
ASSERT_EQ(1, date_cache_version->length());
ASSERT(date_cache_version->get(0)->IsNumber());
date_cache_version->set(0, i::Smi::FromInt(
date_cache_version->get(0)->Number() + 1));
}
......
......@@ -46,6 +46,7 @@ var timezone_cache_timezone;
function LocalTimezone(t) {
if (NUMBER_IS_NAN(t)) return "";
CheckDateCacheCurrent();
if (t == timezone_cache_time) {
return timezone_cache_timezone;
}
......@@ -156,6 +157,7 @@ function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
} else if (IS_STRING(year)) {
// Probe the Date cache. If we already have a time value for the
// given time, we re-use that instead of parsing the string again.
CheckDateCacheCurrent();
var cache = Date_cache;
if (cache.string === year) {
value = cache.time;
......@@ -743,10 +745,22 @@ function DateToJSON(key) {
}
function ResetDateCache() {
var date_cache_version_holder;
var date_cache_version = NAN;
function CheckDateCacheCurrent() {
if (!date_cache_version_holder) {
date_cache_version_holder = %DateCacheVersion();
}
if (date_cache_version_holder[0] == date_cache_version) {
return;
}
date_cache_version = date_cache_version_holder[0];
// Reset the timezone cache:
timezone_cache_time = NAN;
timezone_cache_timezone = undefined;
timezone_cache_timezone = UNDEFINED;
// Reset the date cache:
cache = Date_cache;
......
......@@ -340,6 +340,7 @@ class EternalHandles {
enum SingletonHandle {
I18N_TEMPLATE_ONE,
I18N_TEMPLATE_TWO,
DATE_CACHE_VERSION,
NUMBER_OF_SINGLETON_HANDLES
};
......
......@@ -9612,6 +9612,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateToUTC) {
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCacheVersion) {
HandleScope hs(isolate);
ASSERT(args.length() == 0);
if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
Handle<FixedArray> date_cache_version =
isolate->factory()->NewFixedArray(1, TENURED);
date_cache_version->set(0, Smi::FromInt(0));
isolate->eternal_handles()->CreateSingleton(
isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
}
Handle<FixedArray> date_cache_version =
Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
EternalHandles::DATE_CACHE_VERSION));
// Return result as a JS array.
Handle<JSObject> result =
isolate->factory()->NewJSObject(isolate->array_function());
isolate->factory()->SetContent(Handle<JSArray>::cast(result),
date_cache_version);
return *result;
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
......
......@@ -257,6 +257,7 @@ namespace internal {
F(DateToUTC, 1, 1) \
F(DateMakeDay, 2, 1) \
F(DateSetValue, 3, 1) \
F(DateCacheVersion, 0, 1) \
\
/* Numbers */ \
\
......
......@@ -167,3 +167,25 @@ TEST(DaylightSavingsTime) {
CheckDST(august_20 + 2 * 3600 - 1000);
CheckDST(august_20);
}
TEST(DateCacheVersion) {
FLAG_allow_natives_syntax = true;
v8::Isolate* isolate = CcTest::isolate();
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope scope(isolate);
v8::Handle<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Handle<v8::Array> date_cache_version =
v8::Handle<v8::Array>::Cast(CompileRun("%DateCacheVersion()"));
CHECK_EQ(1, static_cast<int32_t>(date_cache_version->Length()));
CHECK(date_cache_version->Get(0)->IsNumber());
CHECK_EQ(0.0, date_cache_version->Get(0)->NumberValue());
v8::Date::DateTimeConfigurationChangeNotification(isolate);
CHECK_EQ(1, static_cast<int32_t>(date_cache_version->Length()));
CHECK(date_cache_version->Get(0)->IsNumber());
CHECK_EQ(1.0, date_cache_version->Get(0)->NumberValue());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment