Commit 5a04f4fd authored by binji's avatar binji Committed by Commit bot

This is a speculative chain of reverts to improve a Chrome

perf regression. See crbug.com/695653 for more info.

Revert "[SAB] Move Atomics builtins to C++"

This reverts commit 2b9840d8.

Revert "[SAB] Remove unreachable Uint8Clamped atomics paths"

This reverts commit d1160fb1.

Revert "Remove tiny unit test for MinSimple/MaxSimple"

This reverts commit 837760ec.

Revert "Remove infrastructure for experimental JS natives"

This reverts commit 8cfe45b6.

BUG=695653
TBR=hablich@chromium.org

Review-Url: https://codereview.chromium.org/2715223003
Cr-Commit-Position: refs/heads/master@{#43462}
parent a2a2c1b9
......@@ -476,6 +476,43 @@ action("js2c") {
}
}
action("js2c_experimental") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
script = "tools/js2c.py"
# The script depends on this other script, this rule causes a rebuild if it
# changes.
inputs = [
"tools/jsmin.py",
]
# NOSORT
sources = [
"src/js/macros.py",
"src/messages.h",
"src/js/harmony-atomics.js",
]
outputs = [
"$target_gen_dir/experimental-libraries.cc",
]
args = [
rebase_path("$target_gen_dir/experimental-libraries.cc",
root_build_dir),
"EXPERIMENTAL",
] + rebase_path(sources, root_build_dir)
if (v8_use_external_startup_data) {
outputs += [ "$target_gen_dir/libraries_experimental.bin" ]
args += [
"--startup_blob",
rebase_path("$target_gen_dir/libraries_experimental.bin", root_build_dir),
]
}
}
action("js2c_extras") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
......@@ -586,6 +623,7 @@ if (v8_use_external_startup_data) {
deps = [
":js2c",
":js2c_experimental",
":js2c_experimental_extras",
":js2c_extras",
]
......@@ -593,6 +631,7 @@ if (v8_use_external_startup_data) {
# NOSORT
sources = [
"$target_gen_dir/libraries.bin",
"$target_gen_dir/libraries_experimental.bin",
"$target_gen_dir/libraries_extras.bin",
"$target_gen_dir/libraries_experimental_extras.bin",
]
......@@ -755,6 +794,7 @@ v8_source_set("v8_nosnapshot") {
deps = [
":js2c",
":js2c_experimental",
":js2c_experimental_extras",
":js2c_extras",
":v8_base",
......@@ -762,6 +802,7 @@ v8_source_set("v8_nosnapshot") {
sources = [
"$target_gen_dir/experimental-extras-libraries.cc",
"$target_gen_dir/experimental-libraries.cc",
"$target_gen_dir/extras-libraries.cc",
"$target_gen_dir/libraries.cc",
"src/snapshot/snapshot-empty.cc",
......@@ -780,6 +821,7 @@ v8_source_set("v8_snapshot") {
deps = [
":js2c",
":js2c_experimental",
":js2c_experimental_extras",
":js2c_extras",
":v8_base",
......@@ -792,6 +834,7 @@ v8_source_set("v8_snapshot") {
sources = [
"$target_gen_dir/experimental-extras-libraries.cc",
"$target_gen_dir/experimental-libraries.cc",
"$target_gen_dir/extras-libraries.cc",
"$target_gen_dir/libraries.cc",
"$target_gen_dir/snapshot.cc",
......@@ -806,6 +849,7 @@ if (v8_use_external_startup_data) {
deps = [
":js2c",
":js2c_experimental",
":js2c_experimental_extras",
":js2c_extras",
":v8_base",
......
......@@ -57,6 +57,8 @@ Handle<String> Bootstrapper::SourceLookup(int index) {
template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
int index);
template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
int index);
template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
......@@ -131,6 +133,7 @@ void DeleteNativeSources(Object* maybe_array) {
void Bootstrapper::TearDown() {
DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
DeleteNativeSources(
ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));
......@@ -228,6 +231,7 @@ class Genesis BASE_EMBEDDED {
void InstallTypedArray(const char* name, ElementsKind elements_kind,
Handle<JSFunction>* fun);
bool InstallExperimentalNatives();
bool InstallExtraNatives();
bool InstallExperimentalExtraNatives();
bool InstallDebuggerNatives();
......@@ -3056,6 +3060,19 @@ bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
}
bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
HandleScope scope(isolate);
Vector<const char> name = ExperimentalNatives::GetScriptName(index);
Handle<String> source_code =
isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
Handle<Object> global = isolate->global_object();
Handle<Object> utils = isolate->natives_utils_object();
Handle<Object> args[] = {global, utils};
return Bootstrapper::CompileNative(isolate, name, source_code,
arraysize(args), args, NATIVES_CODE);
}
bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
HandleScope scope(isolate);
Vector<const char> name = ExtraNatives::GetScriptName(index);
......@@ -3682,36 +3699,11 @@ void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
Handle<JSObject> atomics_object = factory->NewJSObject(cons, TENURED);
DCHECK(atomics_object->IsJSObject());
JSObject::AddProperty(global, name, atomics_object, DONT_ENUM);
JSObject::AddProperty(atomics_object, factory->to_string_tag_symbol(), name,
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("load"),
Builtins::kAtomicsLoad, 2, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("store"),
Builtins::kAtomicsStore, 3, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("add"),
Builtins::kAtomicsAdd, 3, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("sub"),
Builtins::kAtomicsSub, 3, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("and"),
Builtins::kAtomicsAnd, 3, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("or"),
Builtins::kAtomicsOr, 3, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("xor"),
Builtins::kAtomicsXor, 3, true);
SimpleInstallFunction(atomics_object,
factory->InternalizeUtf8String("exchange"),
Builtins::kAtomicsExchange, 3, true);
SimpleInstallFunction(atomics_object,
factory->InternalizeUtf8String("compareExchange"),
Builtins::kAtomicsCompareExchange, 4, true);
SimpleInstallFunction(atomics_object,
factory->InternalizeUtf8String("isLockFree"),
Builtins::kAtomicsIsLockFree, 1, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("wait"),
Builtins::kAtomicsWait, 4, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("wake"),
Builtins::kAtomicsWake, 3, true);
}
void Genesis::InitializeGlobal_harmony_array_prototype_values() {
......@@ -4315,6 +4307,58 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
return true;
}
bool Genesis::InstallExperimentalNatives() {
static const char* harmony_tailcalls_natives[] = {nullptr};
static const char* harmony_sharedarraybuffer_natives[] = {
"native harmony-atomics.js", NULL};
static const char* harmony_do_expressions_natives[] = {nullptr};
static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
static const char* harmony_regexp_named_captures_natives[] = {nullptr};
static const char* harmony_regexp_property_natives[] = {nullptr};
static const char* harmony_function_sent_natives[] = {nullptr};
static const char* harmony_array_prototype_values_natives[] = {nullptr};
#ifdef V8_I18N_SUPPORT
static const char* icu_case_mapping_natives[] = {nullptr};
static const char* datetime_format_to_parts_natives[] = {nullptr};
#endif
static const char* harmony_restrictive_generators_natives[] = {nullptr};
static const char* harmony_trailing_commas_natives[] = {nullptr};
static const char* harmony_function_tostring_natives[] = {nullptr};
static const char* harmony_class_fields_natives[] = {nullptr};
static const char* harmony_object_rest_spread_natives[] = {nullptr};
static const char* harmony_async_iteration_natives[] = {nullptr};
static const char* harmony_dynamic_import_natives[] = {nullptr};
static const char* harmony_promise_finally_natives[] = {nullptr};
static const char* harmony_template_escapes_natives[] = {nullptr};
for (int i = ExperimentalNatives::GetDebuggerCount();
i < ExperimentalNatives::GetBuiltinsCount(); i++) {
#define INSTALL_EXPERIMENTAL_NATIVES(id, desc) \
if (FLAG_##id) { \
for (size_t j = 0; id##_natives[j] != NULL; j++) { \
Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
if (strncmp(script_name.start(), id##_natives[j], \
script_name.length()) == 0) { \
if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) { \
return false; \
} \
} \
} \
}
HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
#undef INSTALL_EXPERIMENTAL_NATIVES
}
if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
InstallExperimentalBuiltinFunctionIds();
return true;
}
bool Genesis::InstallExtraNatives() {
HandleScope scope(isolate());
......@@ -4346,7 +4390,7 @@ bool Genesis::InstallDebuggerNatives() {
for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
}
return true;
return CallUtilsFunction(isolate(), "PostDebug");
}
......@@ -4384,6 +4428,26 @@ void Genesis::InstallBuiltinFunctionIds() {
}
}
void Genesis::InstallExperimentalBuiltinFunctionIds() {
if (FLAG_harmony_sharedarraybuffer) {
struct BuiltinFunctionIds {
const char* holder_expr;
const char* fun_name;
BuiltinFunctionId id;
};
const BuiltinFunctionIds atomic_builtins[] = {
ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
for (const BuiltinFunctionIds& builtin : atomic_builtins) {
Handle<JSObject> holder =
ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
}
}
}
#undef INSTALL_BUILTIN_ID
......@@ -4894,6 +4958,7 @@ Genesis::Genesis(
if (context_type == FULL_CONTEXT) {
if (!isolate->serializer_enabled()) {
InitializeExperimentalGlobal();
if (!InstallExperimentalNatives()) return;
if (FLAG_experimental_extras) {
if (!InstallExperimentalExtraNatives()) return;
......@@ -4908,6 +4973,8 @@ Genesis::Genesis(
native_context()->set_string_function_prototype_map(
string_function_prototype->map());
}
// The serializer cannot serialize typed arrays. Reset those typed arrays
// for each new context.
} else if (context_type == DEBUG_CONTEXT) {
DCHECK(!isolate->serializer_enabled());
InitializeExperimentalGlobal();
......
......@@ -116,6 +116,7 @@ class Bootstrapper final {
Handle<String> source, int argc,
Handle<Object> argv[], NativesFlag natives_flag);
static bool CompileBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
static bool CompileExtraBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalExtraBuiltin(Isolate* isolate, int index);
......
This diff is collapsed.
......@@ -733,16 +733,6 @@ class Isolate;
CPP(SharedArrayBufferPrototypeGetByteLength) \
TFJ(AtomicsLoad, 2) \
TFJ(AtomicsStore, 3) \
CPP(AtomicsCompareExchange) \
CPP(AtomicsAdd) \
CPP(AtomicsSub) \
CPP(AtomicsAnd) \
CPP(AtomicsOr) \
CPP(AtomicsXor) \
CPP(AtomicsExchange) \
CPP(AtomicsIsLockFree) \
CPP(AtomicsWait) \
CPP(AtomicsWake) \
\
/* String */ \
ASM(StringConstructor) \
......
......@@ -11,10 +11,17 @@
var GlobalArray = global.Array;
var IsNaN = global.isNaN;
var JSONStringify = global.JSON.stringify;
var MapEntries = global.Map.prototype.entries;
var MapIteratorNext = (new global.Map).entries().next;
var SetIteratorNext = (new global.Set).values().next;
var SetValues = global.Set.prototype.values;
var MapEntries;
var MapIteratorNext;
var SetIteratorNext;
var SetValues;
utils.Import(function(from) {
MapEntries = from.MapEntries;
MapIteratorNext = from.MapIteratorNext;
SetIteratorNext = from.SetIteratorNext;
SetValues = from.SetValues;
});
// ----------------------------------------------------------------------------
......
......@@ -2786,6 +2786,9 @@ void Heap::CreateInitialObjects() {
set_natives_source_cache(
*factory->NewFixedArray(Natives::GetBuiltinsCount()));
set_experimental_natives_source_cache(
*factory->NewFixedArray(ExperimentalNatives::GetBuiltinsCount()));
set_extra_natives_source_cache(
*factory->NewFixedArray(ExtraNatives::GetBuiltinsCount()));
......
......@@ -178,6 +178,8 @@ using v8::MemoryPressureLevel;
V(Object, instanceof_cache_map, InstanceofCacheMap) \
V(Object, instanceof_cache_answer, InstanceofCacheAnswer) \
V(FixedArray, natives_source_cache, NativesSourceCache) \
V(FixedArray, experimental_natives_source_cache, \
ExperimentalNativesSourceCache) \
V(FixedArray, extra_natives_source_cache, ExtraNativesSourceCache) \
V(FixedArray, experimental_extra_natives_source_cache, \
ExperimentalExtraNativesSourceCache) \
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function(global, utils) {
"use strict";
%CheckIsBootstrapping();
// -------------------------------------------------------------------
// Imports
var GlobalObject = global.Object;
var MaxSimple;
var MinSimple;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
utils.Import(function(from) {
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
});
// -------------------------------------------------------------------
function CheckSharedIntegerTypedArray(ia) {
if (!%IsSharedIntegerTypedArray(ia)) {
throw %make_type_error(kNotIntegerSharedTypedArray, ia);
}
}
function CheckSharedInteger32TypedArray(ia) {
CheckSharedIntegerTypedArray(ia);
if (!%IsSharedInteger32TypedArray(ia)) {
throw %make_type_error(kNotInt32SharedTypedArray, ia);
}
}
// https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess
function ValidateIndex(index, length) {
var numberIndex = TO_NUMBER(index);
var accessIndex = TO_INTEGER(numberIndex);
if (numberIndex !== accessIndex) {
throw %make_range_error(kInvalidAtomicAccessIndex);
}
if (accessIndex < 0 || accessIndex >= length) {
throw %make_range_error(kInvalidAtomicAccessIndex);
}
return accessIndex;
}
//-------------------------------------------------------------------
function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
CheckSharedIntegerTypedArray(sta);
index = ValidateIndex(index, %_TypedArrayGetLength(sta));
oldValue = TO_NUMBER(oldValue);
newValue = TO_NUMBER(newValue);
return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
}
function AtomicsAddJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
value = TO_NUMBER(value);
return %_AtomicsAdd(ia, index, value);
}
function AtomicsSubJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
value = TO_NUMBER(value);
return %_AtomicsSub(ia, index, value);
}
function AtomicsAndJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
value = TO_NUMBER(value);
return %_AtomicsAnd(ia, index, value);
}
function AtomicsOrJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
value = TO_NUMBER(value);
return %_AtomicsOr(ia, index, value);
}
function AtomicsXorJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
value = TO_NUMBER(value);
return %_AtomicsXor(ia, index, value);
}
function AtomicsExchangeJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
value = TO_NUMBER(value);
return %_AtomicsExchange(ia, index, value);
}
function AtomicsIsLockFreeJS(size) {
return %_AtomicsIsLockFree(TO_INTEGER(size));
}
function AtomicsWaitJS(ia, index, value, timeout) {
CheckSharedInteger32TypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
if (IS_UNDEFINED(timeout)) {
timeout = INFINITY;
} else {
timeout = TO_NUMBER(timeout);
if (NUMBER_IS_NAN(timeout)) {
timeout = INFINITY;
} else {
timeout = MaxSimple(0, timeout);
}
}
return %AtomicsWait(ia, index, value, timeout);
}
function AtomicsWakeJS(ia, index, count) {
CheckSharedInteger32TypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
if (IS_UNDEFINED(count)) {
count = kMaxUint32;
} else {
// Clamp to [0, kMaxUint32].
count = MinSimple(MaxSimple(0, TO_INTEGER(count)), kMaxUint32);
}
return %AtomicsWake(ia, index, count);
}
// -------------------------------------------------------------------
var Atomics = global.Atomics;
// The Atomics global is defined by the bootstrapper.
%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
utils.InstallFunctions(Atomics, DONT_ENUM, [
// TODO(binji): remove the rest of the (non futex) Atomics functions as they
// become builtins.
"compareExchange", AtomicsCompareExchangeJS,
"add", AtomicsAddJS,
"sub", AtomicsSubJS,
"and", AtomicsAndJS,
"or", AtomicsOrJS,
"xor", AtomicsXorJS,
"exchange", AtomicsExchangeJS,
"isLockFree", AtomicsIsLockFreeJS,
"wait", AtomicsWaitJS,
"wake", AtomicsWakeJS,
]);
})
......@@ -12,18 +12,33 @@
// Utils
var imports = UNDEFINED;
var imports_from_experimental = UNDEFINED;
var exports_container = %ExportFromRuntime({});
var typed_array_setup = UNDEFINED;
// Register context value to be initialized with a typed array in
// Genesis::InitializeBuiltinTypedArrays.
function SetupTypedArray(f) {
f.next = typed_array_setup;
typed_array_setup = f;
}
// Export to other scripts.
// In normal natives, this exports functions to other normal natives.
// In experimental natives, this exports to other experimental natives and
// to normal natives that import using utils.ImportFromExperimental.
function Export(f) {
f(exports_container);
}
// Import from other scripts. The actual importing happens in PostNatives so
// that we can import from scripts executed later. However, that means that
// the import is not available until the very end. If the import needs to be
// available immediately, use ImportNow.
// Import from other scripts. The actual importing happens in PostNatives and
// PostExperimental so that we can import from scripts executed later. However,
// that means that the import is not available until the very end. If the
// import needs to be available immediate, use ImportNow.
// In normal natives, this imports from other normal natives.
// In experimental natives, this imports from other experimental natives and
// whitelisted exports from normal natives.
function Import(f) {
f.next = imports;
imports = f;
......@@ -38,6 +53,14 @@ function ImportNow(name) {
}
// In normal natives, import from experimental natives.
// Not callable from experimental natives.
function ImportFromExperimental(f) {
f.next = imports_from_experimental;
imports_from_experimental = f;
}
function SetFunctionName(f, name, prefix) {
if (IS_SYMBOL(name)) {
name = "[" + %SymbolDescription(name) + "]";
......@@ -142,13 +165,82 @@ function PostNatives(utils) {
imports(exports_container);
}
// Whitelist of exports from normal natives to experimental natives and debug.
var expose_list = [
"FormatDateToParts",
"MapEntries",
"MapIteratorNext",
"MaxSimple",
"MinSimple",
"SetIteratorNext",
"SetValues",
"ToLocaleLowerCaseI18N",
"ToLocaleUpperCaseI18N",
"ToLowerCaseI18N",
"ToUpperCaseI18N",
// From runtime:
"promise_result_symbol",
"promise_state_symbol",
"reflect_apply",
"to_string_tag_symbol",
];
var filtered_exports = {};
%OptimizeObjectForAddingMultipleProperties(
filtered_exports, expose_list.length);
for (var key of expose_list) {
filtered_exports[key] = exports_container[key];
}
%ToFastProperties(filtered_exports);
exports_container = filtered_exports;
utils.PostNatives = UNDEFINED;
utils.ImportFromExperimental = UNDEFINED;
}
function PostExperimentals(utils) {
%CheckIsBootstrapping();
for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
imports(exports_container);
}
for ( ; !IS_UNDEFINED(imports_from_experimental);
imports_from_experimental = imports_from_experimental.next) {
imports_from_experimental(exports_container);
}
utils.Export = UNDEFINED;
utils.PostDebug = UNDEFINED;
utils.PostExperimentals = UNDEFINED;
typed_array_setup = UNDEFINED;
}
function PostDebug(utils) {
for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
imports(exports_container);
}
exports_container = UNDEFINED;
utils.Export = UNDEFINED;
utils.Import = UNDEFINED;
utils.ImportNow = UNDEFINED;
utils.PostNatives = UNDEFINED;
utils.PostDebug = UNDEFINED;
utils.PostExperimentals = UNDEFINED;
typed_array_setup = UNDEFINED;
}
function InitializeBuiltinTypedArrays(utils, rng_state, rempio2result) {
var setup_list = typed_array_setup;
for ( ; !IS_UNDEFINED(setup_list); setup_list = setup_list.next) {
setup_list(rng_state, rempio2result);
}
}
// -----------------------------------------------------------------------
%OptimizeObjectForAddingMultipleProperties(utils, 14);
......@@ -156,6 +248,7 @@ function PostNatives(utils) {
utils.Import = Import;
utils.ImportNow = ImportNow;
utils.Export = Export;
utils.ImportFromExperimental = ImportFromExperimental;
utils.SetFunctionName = SetFunctionName;
utils.InstallConstants = InstallConstants;
utils.InstallFunctions = InstallFunctions;
......@@ -163,6 +256,8 @@ utils.InstallGetter = InstallGetter;
utils.OverrideFunction = OverrideFunction;
utils.SetUpLockedPrototype = SetUpLockedPrototype;
utils.PostNatives = PostNatives;
utils.PostExperimentals = PostExperimentals;
utils.PostDebug = PostDebug;
%ToFastProperties(utils);
......
This diff is collapsed.
......@@ -17,6 +17,44 @@
namespace v8 {
namespace internal {
RUNTIME_FUNCTION(Runtime_AtomicsWait) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
CONVERT_SIZE_ARG_CHECKED(index, 1);
CONVERT_INT32_ARG_CHECKED(value, 2);
CONVERT_DOUBLE_ARG_CHECKED(timeout, 3);
CHECK(sta->GetBuffer()->is_shared());
CHECK_LT(index, NumberToSize(sta->length()));
CHECK_EQ(sta->type(), kExternalInt32Array);
CHECK(timeout == V8_INFINITY || !std::isnan(timeout));
if (!isolate->allow_atomics_wait()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kAtomicsWaitNotAllowed));
}
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
return FutexEmulation::Wait(isolate, array_buffer, addr, value, timeout);
}
RUNTIME_FUNCTION(Runtime_AtomicsWake) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
CONVERT_SIZE_ARG_CHECKED(index, 1);
CONVERT_UINT32_ARG_CHECKED(count, 2);
CHECK(sta->GetBuffer()->is_shared());
CHECK_LT(index, NumberToSize(sta->length()));
CHECK_EQ(sta->type(), kExternalInt32Array);
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
return FutexEmulation::Wake(isolate, array_buffer, addr, count);
}
RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
HandleScope scope(isolate);
......
......@@ -63,6 +63,16 @@ namespace internal {
F(ThrowNotIntegerSharedTypedArrayError, 1, 1) \
F(ThrowNotInt32SharedTypedArrayError, 1, 1) \
F(ThrowInvalidAtomicAccessIndexError, 0, 1) \
F(AtomicsCompareExchange, 4, 1) \
F(AtomicsAdd, 3, 1) \
F(AtomicsSub, 3, 1) \
F(AtomicsAnd, 3, 1) \
F(AtomicsOr, 3, 1) \
F(AtomicsXor, 3, 1) \
F(AtomicsExchange, 3, 1) \
F(AtomicsIsLockFree, 1, 1) \
F(AtomicsWait, 4, 1) \
F(AtomicsWake, 3, 1) \
F(AtomicsNumWaitersForTesting, 2, 1) \
F(SetAllowAtomicsWait, 1, 1)
......
......@@ -17,6 +17,12 @@ FixedArray* NativesCollection<CORE>::GetSourceCache(Heap* heap) {
}
template <>
FixedArray* NativesCollection<EXPERIMENTAL>::GetSourceCache(Heap* heap) {
return heap->experimental_natives_source_cache();
}
template <>
FixedArray* NativesCollection<EXTRAS>::GetSourceCache(Heap* heap) {
return heap->extra_natives_source_cache();
......
......@@ -151,6 +151,8 @@ void ReadNatives() {
if (natives_blob_ && NativesHolder<CORE>::empty()) {
SnapshotByteSource bytes(natives_blob_->data, natives_blob_->raw_size);
NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
NativesHolder<EXPERIMENTAL>::set(
NativesStore::MakeFromScriptsSource(&bytes));
NativesHolder<EXTRAS>::set(NativesStore::MakeFromScriptsSource(&bytes));
NativesHolder<EXPERIMENTAL_EXTRAS>::set(
NativesStore::MakeFromScriptsSource(&bytes));
......@@ -179,6 +181,7 @@ void SetNativesFromFile(StartupData* natives_blob) {
*/
void DisposeNatives() {
NativesHolder<CORE>::Dispose();
NativesHolder<EXPERIMENTAL>::Dispose();
NativesHolder<EXTRAS>::Dispose();
NativesHolder<EXPERIMENTAL_EXTRAS>::Dispose();
}
......@@ -230,6 +233,7 @@ Vector<const char> NativesCollection<type>::GetScriptsSource() {
template Vector<const char> NativesCollection<T>::GetScriptName(int i); \
template Vector<const char> NativesCollection<T>::GetScriptsSource();
INSTANTIATE_TEMPLATES(CORE)
INSTANTIATE_TEMPLATES(EXPERIMENTAL)
INSTANTIATE_TEMPLATES(EXTRAS)
INSTANTIATE_TEMPLATES(EXPERIMENTAL_EXTRAS)
#undef INSTANTIATE_TEMPLATES
......
......@@ -15,6 +15,7 @@ namespace internal {
enum NativeType {
CORE,
EXPERIMENTAL,
EXTRAS,
EXPERIMENTAL_EXTRAS,
D8,
......@@ -53,6 +54,7 @@ class V8_EXPORT_PRIVATE NativesCollection {
};
typedef NativesCollection<CORE> Natives;
typedef NativesCollection<EXPERIMENTAL> ExperimentalNatives;
typedef NativesCollection<EXTRAS> ExtraNatives;
typedef NativesCollection<EXPERIMENTAL_EXTRAS> ExperimentalExtraNatives;
......
......@@ -171,6 +171,7 @@
],
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
'<(INTERMEDIATE_DIR)/snapshot.cc',
......@@ -229,6 +230,7 @@
],
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
'snapshot/snapshot-empty.cc',
......@@ -2204,6 +2206,7 @@
'inputs': [
'../tools/concatenate-files.py',
'<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
'<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
'<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin',
'<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin',
],
......@@ -2278,7 +2281,13 @@
'debug/debug.js',
'debug/liveedit.js',
],
'experimental_library_files': [
'js/macros.py',
'messages.h',
'js/harmony-atomics.js',
],
'libraries_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
'libraries_experimental_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
'libraries_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin',
'libraries_experimental_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin',
'conditions': [
......@@ -2320,6 +2329,38 @@
'--nojs',
],
},
{
'action_name': 'js2c_experimental',
'inputs': [
'../tools/js2c.py',
'<@(experimental_library_files)',
],
'outputs': ['<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc'],
'action': [
'python',
'../tools/js2c.py',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'EXPERIMENTAL',
'<@(experimental_library_files)',
],
},
{
'action_name': 'js2c_experimental_bin',
'inputs': [
'../tools/js2c.py',
'<@(experimental_library_files)',
],
'outputs': ['<@(libraries_experimental_bin_file)'],
'action': [
'python',
'../tools/js2c.py',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'EXPERIMENTAL',
'<@(experimental_library_files)',
'--startup_blob', '<@(libraries_experimental_bin_file)',
'--nojs',
],
},
{
'action_name': 'js2c_extras',
'inputs': [
......
......@@ -530,8 +530,8 @@ TEST(SizeOfInitialHeap) {
// requires no extra space.
CompileRun("/*empty*/");
for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) {
// Skip CODE_SPACE, since we had to generate code even for an empty script.
if (i == CODE_SPACE) continue;
// Debug code can be very large, so skip CODE_SPACE if we are generating it.
if (i == CODE_SPACE && i::FLAG_debug_code) continue;
CHECK_EQ(page_count[i], isolate->heap()->paged_space(i)->CountTotalPages());
}
......
......@@ -109,14 +109,6 @@
Atomics.wake(i32a, 0, Number.POSITIVE_INFINITY);
})();
// In a previous version, this test caused a check failure
(function TestObjectWaitValue() {
var sab = new SharedArrayBuffer(16);
var i32a = new Int32Array(sab);
assertEquals("timed-out", Atomics.wait(i32a, 0, Math, 0));
})();
//// WORKER ONLY TESTS
if (this.Worker) {
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-natives-as natives
// Test the MaxSimple and MinSimple internal methods in runtime.js
var MaxSimple = natives.ImportNow("MaxSimple");
var MinSimple = natives.ImportNow("MinSimple");
function checkEvaluations(target) {
var evaluations = 0;
var observedNumber = {
valueOf: function() {
evaluations++;
return 0;
}
};
target(observedNumber, observedNumber);
return evaluations;
}
assertEquals(1, MaxSimple(-1, 1));
assertEquals(2, checkEvaluations(MaxSimple));
assertEquals(-1, MinSimple(-1, 1));
assertEquals(2, checkEvaluations(MinSimple));
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