Commit 02a6727b authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Clean up Intl.DateTimeFormat

Remove numbering_system and change the type of locale
to reduce memory usage of JSDateTimeFormat

Bug: v8:8066
Change-Id: I8a319e05312ffa62f22a382bf150bbe9b48f5f54
Reviewed-on: https://chromium-review.googlesource.com/1242093
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56296}
parent a55e009f
......@@ -1905,8 +1905,7 @@ void JSCollator::JSCollatorVerify(Isolate* isolate) {
void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
VerifyObjectField(isolate, kLocaleOffset);
VerifyObjectField(isolate, kNumberingSystemOffset);
VerifyObjectField(isolate, kICULocaleOffset);
VerifyObjectField(isolate, kICUSimpleDateFormatOffset);
VerifyObjectField(isolate, kBoundFormatOffset);
}
......
......@@ -1969,8 +1969,7 @@ void JSCollator::JSCollatorPrint(std::ostream& os) { // NOLINT
void JSDateTimeFormat::JSDateTimeFormatPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, this, "JSDateTimeFormat");
os << "\n - locale: " << Brief(locale());
os << "\n - numbering system: " << Brief(numbering_system());
os << "\n - icu locale: " << Brief(icu_locale());
os << "\n - icu simple date format: " << Brief(icu_simple_date_format());
os << "\n - bound format: " << Brief(bound_format());
os << "\n";
......
......@@ -18,8 +18,7 @@
namespace v8 {
namespace internal {
ACCESSORS(JSDateTimeFormat, locale, String, kLocaleOffset);
ACCESSORS(JSDateTimeFormat, numbering_system, String, kNumberingSystemOffset);
ACCESSORS(JSDateTimeFormat, icu_locale, Managed<icu::Locale>, kICULocaleOffset);
ACCESSORS(JSDateTimeFormat, icu_simple_date_format,
Managed<icu::SimpleDateFormat>, kICUSimpleDateFormatOffset)
ACCESSORS(JSDateTimeFormat, bound_format, Object, kBoundFormatOffset);
......
......@@ -303,7 +303,12 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
Handle<Object> resolved_obj;
// locale
Handle<String> locale(date_time_format->locale(), isolate);
UErrorCode status = U_ZERO_ERROR;
char language[ULOC_FULLNAME_CAPACITY];
uloc_toLanguageTag(date_time_format->icu_locale()->raw()->getName(), language,
ULOC_FULLNAME_CAPACITY, FALSE, &status);
CHECK(U_SUCCESS(status));
Handle<String> locale = factory->NewStringFromAsciiChecked(language);
CHECK(JSReceiver::CreateDataProperty(
isolate, options, factory->locale_string(), locale, kDontThrow)
.FromJust());
......@@ -332,13 +337,18 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
kDontThrow)
.FromJust());
// numberingSystem
if (date_time_format->numbering_system()->IsString()) {
Handle<String> numbering_system(date_time_format->numbering_system(),
isolate);
CHECK(JSReceiver::CreateDataProperty(isolate, options,
factory->numberingSystem_string(),
numbering_system, kDontThrow)
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
// to assume that for given locale NumberingSystem constructor produces the
// same digits as NumberFormat/Calendar would.
// Tracked by https://unicode-org.atlassian.net/browse/ICU-13431
std::unique_ptr<icu::NumberingSystem> numbering_system(
icu::NumberingSystem::createInstance(
*(date_time_format->icu_locale()->raw()), status));
if (U_SUCCESS(status)) {
CHECK(JSReceiver::CreateDataProperty(
isolate, options, factory->numberingSystem_string(),
factory->NewStringFromAsciiChecked(numbering_system->getName()),
kDontThrow)
.FromJust());
}
......@@ -346,10 +356,10 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
const icu::TimeZone& tz = calendar->getTimeZone();
icu::UnicodeString time_zone;
tz.getID(time_zone);
UErrorCode error = U_ZERO_ERROR;
status = U_ZERO_ERROR;
icu::UnicodeString canonical_time_zone;
icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, error);
if (U_SUCCESS(error)) {
icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, status);
if (U_SUCCESS(status)) {
Handle<String> timezone_value;
// In CLDR (http://unicode.org/cldr/trac/ticket/9943), Etc/UTC is made
// a separate timezone ID from Etc/GMT even though they're still the same
......@@ -732,39 +742,6 @@ std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat(
return date_format;
}
void SetResolvedDateSettings(Isolate* isolate, const icu::Locale& icu_locale,
icu::SimpleDateFormat* date_format,
Handle<JSDateTimeFormat> date_time_format) {
Factory* factory = isolate->factory();
// Set the locale
// 12. Set dateTimeFormat.[[Locale]] to r.[[locale]].
UErrorCode status = U_ZERO_ERROR;
char result[ULOC_FULLNAME_CAPACITY];
uloc_toLanguageTag(icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY,
FALSE, &status);
Handle<String> locale_str = U_SUCCESS(status)
? factory->NewStringFromAsciiChecked(result)
: factory->NewStringFromStaticChars("und");
date_time_format->set_locale(*locale_str);
// TODO(ftang): try to avoid storing numbering_system into JSDateTimeFormat
// later.
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
// to assume that for given locale NumberingSystem constructor produces the
// same digits as NumberFormat/Calendar would.
// 15. Set dateTimeFormat.[[NumberingSystem]] to r.[[nu]].
status = U_ZERO_ERROR;
std::unique_ptr<icu::NumberingSystem> numbering_system(
icu::NumberingSystem::createInstance(icu_locale, status));
if (U_SUCCESS(status)) {
const char* ns = numbering_system->getName();
Handle<String> numbering_system_str =
factory->NewStringFromAsciiChecked(ns);
date_time_format->set_numbering_system(*numbering_system_str);
}
}
} // namespace
enum FormatMatcherOption { kBestFit, kBasic };
......@@ -856,8 +833,15 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
}
}
date_format->adoptCalendar(calendar.release());
SetResolvedDateSettings(isolate, icu_locale, date_format.get(),
date_time_format);
// Set the locale
// 12. Set dateTimeFormat.[[Locale]] to r.[[locale]].
icu::Locale* cloned_locale = icu_locale.clone();
CHECK_NOT_NULL(cloned_locale);
Handle<Managed<icu::Locale>> managed_locale =
Managed<icu::Locale>::FromRawPtr(isolate, 0, cloned_locale);
date_time_format->set_icu_locale(*managed_locale);
Handle<Managed<icu::SimpleDateFormat>> managed_format =
Managed<icu::SimpleDateFormat>::FromUniquePtr(isolate, 0,
std::move(date_format));
......
......@@ -16,6 +16,7 @@
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
class Locale;
class SimpleDateFormat;
}
......@@ -71,12 +72,9 @@ class JSDateTimeFormat : public JSObject {
DECL_CAST(JSDateTimeFormat)
// TODO(ftang): try to remove numbering_system from JSDateTimeFormat and
// directly read from icu to save some bytes later.
// Layout description.
#define JS_DATE_TIME_FORMAT_FIELDS(V) \
V(kLocaleOffset, kPointerSize) \
V(kNumberingSystemOffset, kPointerSize) \
V(kICULocaleOffset, kPointerSize) \
V(kICUSimpleDateFormatOffset, kPointerSize) \
V(kBoundFormatOffset, kPointerSize) \
/* Total size. */ \
......@@ -86,8 +84,7 @@ class JSDateTimeFormat : public JSObject {
JS_DATE_TIME_FORMAT_FIELDS)
#undef JS_DATE_TIME_FORMAT_FIELDS
DECL_ACCESSORS(locale, String)
DECL_ACCESSORS(numbering_system, String)
DECL_ACCESSORS(icu_locale, Managed<icu::Locale>)
DECL_ACCESSORS(icu_simple_date_format, Managed<icu::SimpleDateFormat>)
DECL_ACCESSORS(bound_format, Object)
......
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