Commit 065e9c53 authored by bmeurer's avatar bmeurer Committed by Commit bot

[runtime] Migrate several Date builtins to C++.

Almost all of the Date builtins always call into C++ at least once
anyway, so parsing, compiling and executing the JavaScript wrappers
is just a waste of time.  The most important part here is the Date
constructor itself, which is one of the blockers for new.target in
TurboFan, because compiling the Date constructor takes too much time
with TurboFan (for no reason since we end up in C++ anway).

R=cbruni@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#33109}
parent a94d6d6e
......@@ -6043,8 +6043,9 @@ MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
}
PREPARE_FOR_EXECUTION(context, "Date::New", Value);
Local<Value> result;
has_pending_exception =
!ToLocal<Value>(i::Execution::NewDate(isolate, time), &result);
has_pending_exception = !ToLocal<Value>(
i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
&result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
}
......
......@@ -1249,11 +1249,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
// Builtin functions for Date.prototype.
Handle<JSFunction> date_fun = InstallFunction(
global, "Date", JS_DATE_TYPE, JSDate::kSize,
isolate->initial_object_prototype(), Builtins::kIllegal);
isolate->initial_object_prototype(), Builtins::kDateConstructor);
InstallWithIntrinsicDefaultProto(isolate, date_fun,
Context::DATE_FUNCTION_INDEX);
date_fun->shared()->set_construct_stub(
*isolate->builtins()->JSBuiltinsConstructStub());
*isolate->builtins()->DateConstructor_ConstructStub());
date_fun->shared()->set_length(7);
date_fun->shared()->DontAdaptArguments();
}
{ // -- R e g E x p
......@@ -2530,20 +2532,35 @@ bool Genesis::InstallNatives(ContextType context_type) {
native_context()->set_global_eval_fun(*eval);
}
// Install Date.prototype[@@toPrimitive].
// Setup the Date constructor.
{
Handle<String> key = factory()->Date_string();
Handle<JSFunction> date = Handle<JSFunction>::cast(
Handle<JSFunction> date_fun = Handle<JSFunction>::cast(
Object::GetProperty(handle(native_context()->global_object()), key)
.ToHandleChecked());
Handle<JSObject> proto =
Handle<JSObject>(JSObject::cast(date->instance_prototype()));
Handle<JSObject> prototype =
Handle<JSObject>(JSObject::cast(date_fun->instance_prototype()));
// Install the Date.now, Date.parse and Date.UTC functions.
SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
// Install the "constructor" property on the {prototype}.
JSObject::AddProperty(prototype, factory()->constructor_string(), date_fun,
DONT_ENUM);
// Install the toISOString and valueOf functions.
SimpleInstallFunction(prototype, "toISOString",
Builtins::kDatePrototypeToISOString, 0, false);
SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
0, false);
// Install the @@toPrimitive function.
Handle<JSFunction> to_primitive =
InstallFunction(proto, factory()->to_primitive_symbol(), JS_OBJECT_TYPE,
Handle<JSFunction> to_primitive = InstallFunction(
prototype, factory()->to_primitive_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
Builtins::kDateToPrimitive,
Builtins::kDatePrototypeToPrimitive,
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
// Set the expected parameters for @@toPrimitive to 1; required by builtin.
......
This diff is collapsed.
......@@ -69,7 +69,14 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
V(ArrayBufferConstructor_ConstructStub, kTargetAndNewTarget) \
V(ArrayBufferIsView, kNone) \
\
V(DateToPrimitive, kNone) \
V(DateConstructor, kNone) \
V(DateConstructor_ConstructStub, kTargetAndNewTarget) \
V(DateNow, kNone) \
V(DateParse, kNone) \
V(DateUTC, kNone) \
V(DatePrototypeToISOString, kNone) \
V(DatePrototypeToPrimitive, kNone) \
V(DatePrototypeValueOf, kNone) \
\
V(FunctionConstructor, kTargetAndNewTarget) \
V(FunctionPrototypeBind, kNone) \
......
......@@ -109,7 +109,6 @@ enum BindingFlags {
V(ARRAY_SLICE_INDEX, JSFunction, array_slice) \
V(ARRAY_UNSHIFT_INDEX, JSFunction, array_unshift) \
V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator) \
V(CREATE_DATE_FUN_INDEX, JSFunction, create_date_fun) \
V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
V(ERROR_FUNCTION_INDEX, JSFunction, error_function) \
V(EVAL_ERROR_FUNCTION_INDEX, JSFunction, eval_error_function) \
......
......@@ -175,6 +175,20 @@ int DateCache::DaysFromYearMonth(int year, int month) {
}
void DateCache::BreakDownTime(int64_t time_ms, int* year, int* month, int* day,
int* weekday, int* hour, int* min, int* sec,
int* ms) {
int const days = DaysFromTime(time_ms);
int const time_in_day_ms = TimeInDay(time_ms, days);
YearMonthDayFromDays(days, year, month, day);
*weekday = Weekday(days);
*hour = time_in_day_ms / (60 * 60 * 1000);
*min = (time_in_day_ms / (60 * 1000)) % 60;
*sec = (time_in_day_ms / 1000) % 60;
*ms = time_in_day_ms % 1000;
}
void DateCache::ExtendTheAfterSegment(int time_sec, int offset_ms) {
if (after_->offset_ms == offset_ms &&
after_->start_sec <= time_sec + kDefaultDSTDeltaInSec &&
......
......@@ -190,6 +190,10 @@ class DateCache {
// the first day of the given month in the given year.
int DaysFromYearMonth(int year, int month);
// Breaks down the time value.
void BreakDownTime(int64_t time_ms, int* year, int* month, int* day,
int* weekday, int* hour, int* min, int* sec, int* ms);
// Cache stamp is used for invalidating caches in JSDate.
// We increment the stamp each time when the timezone information changes.
// JSDate objects perform stamp check and invalidate their caches if
......
......@@ -6,7 +6,6 @@
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/deoptimizer.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
#include "src/vm-state-inl.h"
......@@ -421,22 +420,6 @@ void StackGuard::InitThread(const ExecutionAccess& lock) {
// --- C a l l s t o n a t i v e s ---
#define RETURN_NATIVE_CALL(name, args) \
do { \
Handle<Object> argv[] = args; \
return Call(isolate, isolate->name##_fun(), \
isolate->factory()->undefined_value(), arraysize(argv), argv); \
} while (false)
MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
Handle<Object> time_obj = isolate->factory()->NewNumber(time);
RETURN_NATIVE_CALL(create_date, { time_obj });
}
#undef RETURN_NATIVE_CALL
MaybeHandle<Object> Execution::ToObject(Isolate* isolate, Handle<Object> obj) {
Handle<JSReceiver> receiver;
......
......@@ -13,9 +13,6 @@
namespace v8 {
namespace internal {
// Forward declarations.
class JSRegExp;
class Execution final : public AllStatic {
public:
// Call a function, the caller supplies a receiver and an array
......@@ -56,10 +53,6 @@ class Execution final : public AllStatic {
MUST_USE_RESULT static MaybeHandle<Object> ToObject(
Isolate* isolate, Handle<Object> obj);
// Create a new date object from 'time'.
MUST_USE_RESULT static MaybeHandle<Object> NewDate(
Isolate* isolate, double time);
static Handle<String> GetStackTraceLine(Handle<Object> recv,
Handle<JSFunction> fun,
Handle<Object> pos,
......
......@@ -49,14 +49,6 @@ function LocalTimezone(t) {
}
function UTC(time) {
if (NUMBER_IS_NAN(time)) return time;
// local_time_offset is needed before the call to DaylightSavingsOffset,
// so it may be uninitialized.
return %DateToUTC(time);
}
// ECMA 262 - 15.9.1.11
function MakeTime(hour, min, sec, ms) {
if (!IsFinite(hour)) return NaN;
......@@ -115,80 +107,6 @@ function TimeClip(time) {
}
// The Date cache is used to limit the cost of parsing the same Date
// strings over and over again.
var Date_cache = {
// Cached time value.
time: 0,
// String input for which the cached time is valid.
string: null
};
function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
if (IS_UNDEFINED(new.target)) {
// ECMA 262 - 15.9.2
return %_Call(DateToString, new GlobalDate());
}
// ECMA 262 - 15.9.3
var argc = %_ArgumentsLength();
var value;
var result;
if (argc == 0) {
value = %DateCurrentTime();
result = %NewObject(GlobalDate, new.target);
SET_UTC_DATE_VALUE(result, value);
} else if (argc == 1) {
if (IS_NUMBER(year)) {
value = TimeClip(year);
} 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;
} else {
value = DateParse(year);
if (!NUMBER_IS_NAN(value)) {
cache.time = value;
cache.string = year;
}
}
} else if (IS_DATE(year)) {
value = UTC_DATE_VALUE(year);
} else {
var time = TO_PRIMITIVE(year);
value = IS_STRING(time) ? DateParse(time) : TO_NUMBER(time);
}
result = %NewObject(GlobalDate, new.target);
SET_UTC_DATE_VALUE(result, value);
} else {
year = TO_NUMBER(year);
month = TO_NUMBER(month);
date = argc > 2 ? TO_NUMBER(date) : 1;
hours = argc > 3 ? TO_NUMBER(hours) : 0;
minutes = argc > 4 ? TO_NUMBER(minutes) : 0;
seconds = argc > 5 ? TO_NUMBER(seconds) : 0;
ms = argc > 6 ? TO_NUMBER(ms) : 0;
year = (!NUMBER_IS_NAN(year) &&
0 <= TO_INTEGER(year) &&
TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
var day = MakeDay(year, month, date);
var time = MakeTime(hours, minutes, seconds, ms);
value = MakeDate(day, time);
result = %NewObject(GlobalDate, new.target);
SET_LOCAL_DATE_VALUE(result, value);
}
return result;
}
var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
......@@ -260,51 +178,6 @@ function DatePrintString(date) {
// -------------------------------------------------------------------
// Reused output buffer. Used when parsing date strings.
var parse_buffer = new InternalArray(8);
// ECMA 262 - 15.9.4.2
function DateParse(string) {
var arr = %DateParseString(string, parse_buffer);
if (IS_NULL(arr)) return NaN;
var day = MakeDay(arr[0], arr[1], arr[2]);
var time = MakeTime(arr[3], arr[4], arr[5], arr[6]);
var date = MakeDate(day, time);
if (IS_NULL(arr[7])) {
return TimeClip(UTC(date));
} else {
return TimeClip(date - arr[7] * 1000);
}
}
// ECMA 262 - 15.9.4.3
function DateUTC(year, month, date, hours, minutes, seconds, ms) {
year = TO_NUMBER(year);
month = TO_NUMBER(month);
var argc = %_ArgumentsLength();
date = argc > 2 ? TO_NUMBER(date) : 1;
hours = argc > 3 ? TO_NUMBER(hours) : 0;
minutes = argc > 4 ? TO_NUMBER(minutes) : 0;
seconds = argc > 5 ? TO_NUMBER(seconds) : 0;
ms = argc > 6 ? TO_NUMBER(ms) : 0;
year = (!NUMBER_IS_NAN(year) &&
0 <= TO_INTEGER(year) &&
TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
var day = MakeDay(year, month, date);
var time = MakeTime(hours, minutes, seconds, ms);
return TimeClip(MakeDate(day, time));
}
// ECMA 262 - 15.9.4.4
function DateNow() {
return %DateCurrentTime();
}
// ECMA 262 - 15.9.5.2
function DateToString() {
CHECK_DATE(this);
......@@ -359,13 +232,6 @@ function DateToLocaleTimeString() {
}
// ECMA 262 - 15.9.5.8
function DateValueOf() {
CHECK_DATE(this);
return UTC_DATE_VALUE(this);
}
// ECMA 262 - 15.9.5.9
function DateGetTime() {
CHECK_DATE(this);
......@@ -739,39 +605,6 @@ function DateToGMTString() {
}
function PadInt(n, digits) {
if (digits == 1) return n;
return n < %_MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
}
// ECMA 262 - 20.3.4.36
function DateToISOString() {
CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) throw MakeRangeError(kInvalidTimeValue);
var year = UTC_YEAR(this);
var year_string;
if (year >= 0 && year <= 9999) {
year_string = PadInt(year, 4);
} else {
if (year < 0) {
year_string = "-" + PadInt(-year, 6);
} else {
year_string = "+" + PadInt(year, 6);
}
}
return year_string +
'-' + PadInt(UTC_MONTH(this) + 1, 2) +
'-' + PadInt(UTC_DAY(this), 2) +
'T' + PadInt(UTC_HOUR(this), 2) +
':' + PadInt(UTC_MIN(this), 2) +
':' + PadInt(UTC_SEC(this), 2) +
'.' + PadInt(UTC_MS(this), 3) +
'Z';
}
// 20.3.4.37 Date.prototype.toJSON ( key )
function DateToJSON(key) {
var o = TO_OBJECT(this);
......@@ -800,34 +633,12 @@ function CheckDateCacheCurrent() {
// Reset the timezone cache:
timezone_cache_time = NaN;
timezone_cache_timezone = UNDEFINED;
// Reset the date cache:
Date_cache.time = NaN;
Date_cache.string = null;
}
function CreateDate(time) {
var date = new GlobalDate();
date.setTime(time);
return date;
}
// -------------------------------------------------------------------
%SetCode(GlobalDate, DateConstructor);
%FunctionSetPrototype(GlobalDate, new GlobalObject());
// Set up non-enumerable properties of the Date object itself.
utils.InstallFunctions(GlobalDate, DONT_ENUM, [
"UTC", DateUTC,
"parse", DateParse,
"now", DateNow
]);
// Set up non-enumerable constructor property of the Date prototype object.
%AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM);
// Set up non-enumerable functions of the Date prototype object and
// set their names.
utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
......@@ -837,7 +648,6 @@ utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
"toLocaleString", DateToLocaleString,
"toLocaleDateString", DateToLocaleDateString,
"toLocaleTimeString", DateToLocaleTimeString,
"valueOf", DateValueOf,
"getTime", DateGetTime,
"getFullYear", DateGetFullYear,
"getUTCFullYear", DateGetUTCFullYear,
......@@ -875,10 +685,7 @@ utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
"toUTCString", DateToUTCString,
"getYear", DateGetYear,
"setYear", DateSetYear,
"toISOString", DateToISOString,
"toJSON", DateToJSON
]);
%InstallToContext(["create_date_fun", CreateDate]);
})
......@@ -1027,6 +1027,33 @@ Object* FunctionTemplateInfo::GetCompatibleReceiver(Isolate* isolate,
}
// static
MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
Handle<JSReceiver> new_target,
Handle<AllocationSite> site) {
// If called through new, new.target can be:
// - a subclass of constructor,
// - a proxy wrapper around constructor, or
// - the constructor itself.
// If called through Reflect.construct, it's guaranteed to be a constructor.
Isolate* const isolate = constructor->GetIsolate();
DCHECK(constructor->IsConstructor());
DCHECK(new_target->IsConstructor());
DCHECK(!constructor->has_initial_map() ||
constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
Handle<Map> initial_map;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, initial_map,
JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
Handle<JSObject> result =
isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
isolate->counters()->constructed_objects()->Increment();
isolate->counters()->constructed_objects_runtime()->Increment();
return result;
}
Handle<FixedArray> JSObject::EnsureWritableFastElements(
Handle<JSObject> object) {
DCHECK(object->HasFastSmiOrObjectElements());
......@@ -19094,6 +19121,39 @@ int BreakPointInfo::GetBreakPointCount() {
}
// static
MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
Handle<JSReceiver> new_target, double tv) {
Isolate* const isolate = constructor->GetIsolate();
Handle<JSObject> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
JSObject::New(constructor, new_target), JSDate);
if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
tv = DoubleToInteger(tv) + 0.0;
} else {
tv = std::numeric_limits<double>::quiet_NaN();
}
Handle<Object> value = isolate->factory()->NewNumber(tv);
Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
return Handle<JSDate>::cast(result);
}
// static
double JSDate::CurrentTimeValue(Isolate* isolate) {
if (FLAG_log_timer_events || FLAG_prof_cpp) LOG(isolate, CurrentTimeEvent());
// According to ECMA-262, section 15.9.1, page 117, the precision of
// the number in a Date object representing a particular instant in
// time is milliseconds. Therefore, we floor the result of getting
// the OS time.
return Floor(FLAG_verify_predictable
? isolate->heap()->MonotonicallyIncreasingTimeInMs()
: base::OS::TimeCurrentMillis());
}
// static
Object* JSDate::GetField(Object* object, Smi* index) {
return JSDate::cast(object)->DoGetField(
static_cast<FieldIndex>(index->value()));
......
......@@ -1967,6 +1967,10 @@ class JSReceiver: public HeapObject {
// caching.
class JSObject: public JSReceiver {
public:
static MUST_USE_RESULT MaybeHandle<JSObject> New(
Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
Handle<AllocationSite> site = Handle<AllocationSite>::null());
// [properties]: Backing storage for properties.
// properties is a FixedArray in the fast case and a Dictionary in the
// slow case.
......@@ -7530,6 +7534,10 @@ class DateCache;
// Representation for JS date objects.
class JSDate: public JSObject {
public:
static MUST_USE_RESULT MaybeHandle<JSDate> New(Handle<JSFunction> constructor,
Handle<JSReceiver> new_target,
double tv);
// If one component is NaN, all of them are, indicating a NaN time value.
// [value]: the time value.
DECL_ACCESSORS(value, Object)
......@@ -7553,6 +7561,9 @@ class JSDate: public JSObject {
DECLARE_CAST(JSDate)
// Returns the time value (UTC) identifying the current time.
static double CurrentTimeValue(Isolate* isolate);
// Returns the date field with the specified index.
// See FieldIndex for the list of date fields.
static Object* GetField(Object* date, Smi* index);
......
......@@ -7,7 +7,6 @@
#include "src/arguments.h"
#include "src/conversions-inl.h"
#include "src/date.h"
#include "src/dateparser-inl.h"
#include "src/factory.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
......@@ -79,58 +78,8 @@ RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
if (FLAG_log_timer_events || FLAG_prof_cpp) LOG(isolate, CurrentTimeEvent());
// According to ECMA-262, section 15.9.1, page 117, the precision of
// the number in a Date object representing a particular instant in
// time is milliseconds. Therefore, we floor the result of getting
// the OS time.
double millis;
if (FLAG_verify_predictable) {
millis = Floor(isolate->heap()->MonotonicallyIncreasingTimeInMs());
} else {
millis = Floor(base::OS::TimeCurrentMillis());
}
return *isolate->factory()->NewNumber(millis);
}
RUNTIME_FUNCTION(Runtime_DateParseString) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
RUNTIME_ASSERT(output->HasFastElements());
JSObject::EnsureCanContainHeapObjectElements(output);
RUNTIME_ASSERT(output->HasFastObjectElements());
Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
Handle<String> str;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, str,
Object::ToString(isolate, input));
str = String::Flatten(str);
DisallowHeapAllocation no_gc;
bool result;
String::FlatContent str_content = str->GetFlatContent();
if (str_content.IsOneByte()) {
result = DateParser::Parse(str_content.ToOneByteVector(), *output_array,
isolate->unicode_cache());
} else {
DCHECK(str_content.IsTwoByte());
result = DateParser::Parse(str_content.ToUC16Vector(), *output_array,
isolate->unicode_cache());
}
if (result) {
return *output;
} else {
return isolate->heap()->null_value();
}
DCHECK_EQ(0, args.length());
return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
}
......@@ -149,19 +98,6 @@ RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
}
RUNTIME_FUNCTION(Runtime_DateToUTC) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
x <= DateCache::kMaxTimeBeforeUTCInMs);
int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
return *isolate->factory()->NewNumber(static_cast<double>(time));
}
RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
HandleScope hs(isolate);
DCHECK(args.length() == 0);
......
......@@ -389,10 +389,11 @@ RUNTIME_FUNCTION(Runtime_InternalDateParse) {
UDate date = date_format->parse(u_date, status);
if (U_FAILURE(status)) return isolate->heap()->undefined_value();
Handle<Object> result;
Handle<JSDate> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, Execution::NewDate(isolate, static_cast<double>(date)));
DCHECK(result->IsJSDate());
isolate, result,
JSDate::New(isolate->date_function(), isolate->date_function(),
static_cast<double>(date)));
return *result;
}
......
......@@ -795,46 +795,15 @@ RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
}
static Object* Runtime_NewObjectHelper(Isolate* isolate,
Handle<JSFunction> constructor,
Handle<JSReceiver> new_target,
Handle<AllocationSite> site) {
DCHECK(constructor->IsConstructor());
// If called through new, new.target can be:
// - a subclass of constructor,
// - a proxy wrapper around constructor, or
// - the constructor itself.
// If called through Reflect.construct, it's guaranteed to be a constructor by
// REFLECT_CONSTRUCT_PREPARE.
DCHECK(new_target->IsConstructor());
DCHECK(!constructor->has_initial_map() ||
constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
Handle<Map> initial_map;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, initial_map,
JSFunction::GetDerivedMap(isolate, constructor, new_target));
Handle<JSObject> result =
isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
isolate->counters()->constructed_objects()->Increment();
isolate->counters()->constructed_objects_runtime()->Increment();
return *result;
}
RUNTIME_FUNCTION(Runtime_NewObject) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
return Runtime_NewObjectHelper(isolate, constructor, new_target,
Handle<AllocationSite>::null());
Handle<JSObject> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
JSObject::New(target, new_target));
return *result;
}
......
......@@ -141,9 +141,7 @@ namespace internal {
F(IsDate, 1, 1) \
F(ThrowNotDateError, 0, 1) \
F(DateCurrentTime, 0, 1) \
F(DateParseString, 2, 1) \
F(DateLocalTimezone, 1, 1) \
F(DateToUTC, 1, 1) \
F(DateCacheVersion, 0, 1) \
F(DateField, 2 /* date object, field index */, 1)
......
......@@ -75,7 +75,6 @@ testTraceNativeConversion(RegExp); // Does ToString on argument.
testTraceNativeConstructor(String); // Does ToString on argument.
testTraceNativeConstructor(Number); // Does ToNumber on argument.
testTraceNativeConstructor(RegExp); // Does ToString on argument.
testTraceNativeConstructor(Date); // Does ToNumber on argument.
// QuickSort has builtins object as receiver, and is non-native
// builtin. Should not be omitted with the --builtins-in-stack-traces flag.
......
......@@ -297,7 +297,6 @@ testTraceNativeConversion(RegExp); // Does ToString on argument.
testTraceNativeConstructor(String); // Does ToString on argument.
testTraceNativeConstructor(Number); // Does ToNumber on argument.
testTraceNativeConstructor(RegExp); // Does ToString on argument.
testTraceNativeConstructor(Date); // Does ToNumber on argument.
// Omitted because QuickSort has builtins object as receiver, and is non-native
// builtin.
......
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