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
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));
}
function LocalTimezone(t) {
if (NUMBER_IS_NAN(t)) return "";
+ CheckDateCacheCurrent();
if (t == timezone_cache_time) {
return timezone_cache_timezone;
}
} 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;
}
-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;
enum SingletonHandle {
I18N_TEMPLATE_ONE,
I18N_TEMPLATE_TWO,
+ DATE_CACHE_VERSION,
NUMBER_OF_SINGLETON_HANDLES
};
}
+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);
F(DateToUTC, 1, 1) \
F(DateMakeDay, 2, 1) \
F(DateSetValue, 3, 1) \
+ F(DateCacheVersion, 0, 1) \
\
/* Numbers */ \
\
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());
+}