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") { ...@@ -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") { action("js2c_extras") {
visibility = [ ":*" ] # Only targets in this file can depend on this. visibility = [ ":*" ] # Only targets in this file can depend on this.
...@@ -586,6 +623,7 @@ if (v8_use_external_startup_data) { ...@@ -586,6 +623,7 @@ if (v8_use_external_startup_data) {
deps = [ deps = [
":js2c", ":js2c",
":js2c_experimental",
":js2c_experimental_extras", ":js2c_experimental_extras",
":js2c_extras", ":js2c_extras",
] ]
...@@ -593,6 +631,7 @@ if (v8_use_external_startup_data) { ...@@ -593,6 +631,7 @@ if (v8_use_external_startup_data) {
# NOSORT # NOSORT
sources = [ sources = [
"$target_gen_dir/libraries.bin", "$target_gen_dir/libraries.bin",
"$target_gen_dir/libraries_experimental.bin",
"$target_gen_dir/libraries_extras.bin", "$target_gen_dir/libraries_extras.bin",
"$target_gen_dir/libraries_experimental_extras.bin", "$target_gen_dir/libraries_experimental_extras.bin",
] ]
...@@ -755,6 +794,7 @@ v8_source_set("v8_nosnapshot") { ...@@ -755,6 +794,7 @@ v8_source_set("v8_nosnapshot") {
deps = [ deps = [
":js2c", ":js2c",
":js2c_experimental",
":js2c_experimental_extras", ":js2c_experimental_extras",
":js2c_extras", ":js2c_extras",
":v8_base", ":v8_base",
...@@ -762,6 +802,7 @@ v8_source_set("v8_nosnapshot") { ...@@ -762,6 +802,7 @@ v8_source_set("v8_nosnapshot") {
sources = [ sources = [
"$target_gen_dir/experimental-extras-libraries.cc", "$target_gen_dir/experimental-extras-libraries.cc",
"$target_gen_dir/experimental-libraries.cc",
"$target_gen_dir/extras-libraries.cc", "$target_gen_dir/extras-libraries.cc",
"$target_gen_dir/libraries.cc", "$target_gen_dir/libraries.cc",
"src/snapshot/snapshot-empty.cc", "src/snapshot/snapshot-empty.cc",
...@@ -780,6 +821,7 @@ v8_source_set("v8_snapshot") { ...@@ -780,6 +821,7 @@ v8_source_set("v8_snapshot") {
deps = [ deps = [
":js2c", ":js2c",
":js2c_experimental",
":js2c_experimental_extras", ":js2c_experimental_extras",
":js2c_extras", ":js2c_extras",
":v8_base", ":v8_base",
...@@ -792,6 +834,7 @@ v8_source_set("v8_snapshot") { ...@@ -792,6 +834,7 @@ v8_source_set("v8_snapshot") {
sources = [ sources = [
"$target_gen_dir/experimental-extras-libraries.cc", "$target_gen_dir/experimental-extras-libraries.cc",
"$target_gen_dir/experimental-libraries.cc",
"$target_gen_dir/extras-libraries.cc", "$target_gen_dir/extras-libraries.cc",
"$target_gen_dir/libraries.cc", "$target_gen_dir/libraries.cc",
"$target_gen_dir/snapshot.cc", "$target_gen_dir/snapshot.cc",
...@@ -806,6 +849,7 @@ if (v8_use_external_startup_data) { ...@@ -806,6 +849,7 @@ if (v8_use_external_startup_data) {
deps = [ deps = [
":js2c", ":js2c",
":js2c_experimental",
":js2c_experimental_extras", ":js2c_experimental_extras",
":js2c_extras", ":js2c_extras",
":v8_base", ":v8_base",
......
...@@ -57,6 +57,8 @@ Handle<String> Bootstrapper::SourceLookup(int index) { ...@@ -57,6 +57,8 @@ Handle<String> Bootstrapper::SourceLookup(int index) {
template Handle<String> Bootstrapper::SourceLookup<Natives>(int index); template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
int index);
template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>( template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
int index); int index);
template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index); template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
...@@ -131,6 +133,7 @@ void DeleteNativeSources(Object* maybe_array) { ...@@ -131,6 +133,7 @@ void DeleteNativeSources(Object* maybe_array) {
void Bootstrapper::TearDown() { void Bootstrapper::TearDown() {
DeleteNativeSources(Natives::GetSourceCache(isolate_->heap())); DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap())); DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
DeleteNativeSources( DeleteNativeSources(
ExperimentalExtraNatives::GetSourceCache(isolate_->heap())); ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));
...@@ -228,6 +231,7 @@ class Genesis BASE_EMBEDDED { ...@@ -228,6 +231,7 @@ class Genesis BASE_EMBEDDED {
void InstallTypedArray(const char* name, ElementsKind elements_kind, void InstallTypedArray(const char* name, ElementsKind elements_kind,
Handle<JSFunction>* fun); Handle<JSFunction>* fun);
bool InstallExperimentalNatives();
bool InstallExtraNatives(); bool InstallExtraNatives();
bool InstallExperimentalExtraNatives(); bool InstallExperimentalExtraNatives();
bool InstallDebuggerNatives(); bool InstallDebuggerNatives();
...@@ -3056,6 +3060,19 @@ bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) { ...@@ -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) { bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
HandleScope scope(isolate); HandleScope scope(isolate);
Vector<const char> name = ExtraNatives::GetScriptName(index); Vector<const char> name = ExtraNatives::GetScriptName(index);
...@@ -3682,36 +3699,11 @@ void Genesis::InitializeGlobal_harmony_sharedarraybuffer() { ...@@ -3682,36 +3699,11 @@ void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
Handle<JSObject> atomics_object = factory->NewJSObject(cons, TENURED); Handle<JSObject> atomics_object = factory->NewJSObject(cons, TENURED);
DCHECK(atomics_object->IsJSObject()); DCHECK(atomics_object->IsJSObject());
JSObject::AddProperty(global, name, atomics_object, DONT_ENUM); 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"), SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("load"),
Builtins::kAtomicsLoad, 2, true); Builtins::kAtomicsLoad, 2, true);
SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("store"), SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("store"),
Builtins::kAtomicsStore, 3, true); 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() { void Genesis::InitializeGlobal_harmony_array_prototype_values() {
...@@ -4315,6 +4307,58 @@ bool Genesis::InstallNatives(GlobalContextType context_type) { ...@@ -4315,6 +4307,58 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
return true; 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() { bool Genesis::InstallExtraNatives() {
HandleScope scope(isolate()); HandleScope scope(isolate());
...@@ -4346,7 +4390,7 @@ bool Genesis::InstallDebuggerNatives() { ...@@ -4346,7 +4390,7 @@ bool Genesis::InstallDebuggerNatives() {
for (int i = 0; i < Natives::GetDebuggerCount(); ++i) { for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false; if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
} }
return true; return CallUtilsFunction(isolate(), "PostDebug");
} }
...@@ -4384,6 +4428,26 @@ void Genesis::InstallBuiltinFunctionIds() { ...@@ -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 #undef INSTALL_BUILTIN_ID
...@@ -4894,6 +4958,7 @@ Genesis::Genesis( ...@@ -4894,6 +4958,7 @@ Genesis::Genesis(
if (context_type == FULL_CONTEXT) { if (context_type == FULL_CONTEXT) {
if (!isolate->serializer_enabled()) { if (!isolate->serializer_enabled()) {
InitializeExperimentalGlobal(); InitializeExperimentalGlobal();
if (!InstallExperimentalNatives()) return;
if (FLAG_experimental_extras) { if (FLAG_experimental_extras) {
if (!InstallExperimentalExtraNatives()) return; if (!InstallExperimentalExtraNatives()) return;
...@@ -4908,6 +4973,8 @@ Genesis::Genesis( ...@@ -4908,6 +4973,8 @@ Genesis::Genesis(
native_context()->set_string_function_prototype_map( native_context()->set_string_function_prototype_map(
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) { } else if (context_type == DEBUG_CONTEXT) {
DCHECK(!isolate->serializer_enabled()); DCHECK(!isolate->serializer_enabled());
InitializeExperimentalGlobal(); InitializeExperimentalGlobal();
......
...@@ -116,6 +116,7 @@ class Bootstrapper final { ...@@ -116,6 +116,7 @@ class Bootstrapper final {
Handle<String> source, int argc, Handle<String> source, int argc,
Handle<Object> argv[], NativesFlag natives_flag); Handle<Object> argv[], NativesFlag natives_flag);
static bool CompileBuiltin(Isolate* isolate, int index); static bool CompileBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
static bool CompileExtraBuiltin(Isolate* isolate, int index); static bool CompileExtraBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalExtraBuiltin(Isolate* isolate, int index); static bool CompileExperimentalExtraBuiltin(Isolate* isolate, int index);
......
This diff is collapsed.
...@@ -733,16 +733,6 @@ class Isolate; ...@@ -733,16 +733,6 @@ class Isolate;
CPP(SharedArrayBufferPrototypeGetByteLength) \ CPP(SharedArrayBufferPrototypeGetByteLength) \
TFJ(AtomicsLoad, 2) \ TFJ(AtomicsLoad, 2) \
TFJ(AtomicsStore, 3) \ TFJ(AtomicsStore, 3) \
CPP(AtomicsCompareExchange) \
CPP(AtomicsAdd) \
CPP(AtomicsSub) \
CPP(AtomicsAnd) \
CPP(AtomicsOr) \
CPP(AtomicsXor) \
CPP(AtomicsExchange) \
CPP(AtomicsIsLockFree) \
CPP(AtomicsWait) \
CPP(AtomicsWake) \
\ \
/* String */ \ /* String */ \
ASM(StringConstructor) \ ASM(StringConstructor) \
......
...@@ -11,10 +11,17 @@ ...@@ -11,10 +11,17 @@
var GlobalArray = global.Array; var GlobalArray = global.Array;
var IsNaN = global.isNaN; var IsNaN = global.isNaN;
var JSONStringify = global.JSON.stringify; var JSONStringify = global.JSON.stringify;
var MapEntries = global.Map.prototype.entries; var MapEntries;
var MapIteratorNext = (new global.Map).entries().next; var MapIteratorNext;
var SetIteratorNext = (new global.Set).values().next; var SetIteratorNext;
var SetValues = global.Set.prototype.values; 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() { ...@@ -2786,6 +2786,9 @@ void Heap::CreateInitialObjects() {
set_natives_source_cache( set_natives_source_cache(
*factory->NewFixedArray(Natives::GetBuiltinsCount())); *factory->NewFixedArray(Natives::GetBuiltinsCount()));
set_experimental_natives_source_cache(
*factory->NewFixedArray(ExperimentalNatives::GetBuiltinsCount()));
set_extra_natives_source_cache( set_extra_natives_source_cache(
*factory->NewFixedArray(ExtraNatives::GetBuiltinsCount())); *factory->NewFixedArray(ExtraNatives::GetBuiltinsCount()));
......
...@@ -178,6 +178,8 @@ using v8::MemoryPressureLevel; ...@@ -178,6 +178,8 @@ using v8::MemoryPressureLevel;
V(Object, instanceof_cache_map, InstanceofCacheMap) \ V(Object, instanceof_cache_map, InstanceofCacheMap) \
V(Object, instanceof_cache_answer, InstanceofCacheAnswer) \ V(Object, instanceof_cache_answer, InstanceofCacheAnswer) \
V(FixedArray, natives_source_cache, NativesSourceCache) \ V(FixedArray, natives_source_cache, NativesSourceCache) \
V(FixedArray, experimental_natives_source_cache, \
ExperimentalNativesSourceCache) \
V(FixedArray, extra_natives_source_cache, ExtraNativesSourceCache) \ V(FixedArray, extra_natives_source_cache, ExtraNativesSourceCache) \
V(FixedArray, experimental_extra_natives_source_cache, \ V(FixedArray, experimental_extra_natives_source_cache, \
ExperimentalExtraNativesSourceCache) \ 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 @@ ...@@ -12,18 +12,33 @@
// Utils // Utils
var imports = UNDEFINED; var imports = UNDEFINED;
var imports_from_experimental = UNDEFINED;
var exports_container = %ExportFromRuntime({}); 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. // 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) { function Export(f) {
f(exports_container); f(exports_container);
} }
// Import from other scripts. The actual importing happens in PostNatives so // Import from other scripts. The actual importing happens in PostNatives and
// that we can import from scripts executed later. However, that means that // PostExperimental so that we can import from scripts executed later. However,
// the import is not available until the very end. If the import needs to be // that means that the import is not available until the very end. If the
// available immediately, use ImportNow. // 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) { function Import(f) {
f.next = imports; f.next = imports;
imports = f; imports = f;
...@@ -38,6 +53,14 @@ function ImportNow(name) { ...@@ -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) { function SetFunctionName(f, name, prefix) {
if (IS_SYMBOL(name)) { if (IS_SYMBOL(name)) {
name = "[" + %SymbolDescription(name) + "]"; name = "[" + %SymbolDescription(name) + "]";
...@@ -142,13 +165,82 @@ function PostNatives(utils) { ...@@ -142,13 +165,82 @@ function PostNatives(utils) {
imports(exports_container); 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; exports_container = UNDEFINED;
utils.Export = UNDEFINED; utils.Export = UNDEFINED;
utils.Import = UNDEFINED; utils.Import = UNDEFINED;
utils.ImportNow = 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); %OptimizeObjectForAddingMultipleProperties(utils, 14);
...@@ -156,6 +248,7 @@ function PostNatives(utils) { ...@@ -156,6 +248,7 @@ function PostNatives(utils) {
utils.Import = Import; utils.Import = Import;
utils.ImportNow = ImportNow; utils.ImportNow = ImportNow;
utils.Export = Export; utils.Export = Export;
utils.ImportFromExperimental = ImportFromExperimental;
utils.SetFunctionName = SetFunctionName; utils.SetFunctionName = SetFunctionName;
utils.InstallConstants = InstallConstants; utils.InstallConstants = InstallConstants;
utils.InstallFunctions = InstallFunctions; utils.InstallFunctions = InstallFunctions;
...@@ -163,6 +256,8 @@ utils.InstallGetter = InstallGetter; ...@@ -163,6 +256,8 @@ utils.InstallGetter = InstallGetter;
utils.OverrideFunction = OverrideFunction; utils.OverrideFunction = OverrideFunction;
utils.SetUpLockedPrototype = SetUpLockedPrototype; utils.SetUpLockedPrototype = SetUpLockedPrototype;
utils.PostNatives = PostNatives; utils.PostNatives = PostNatives;
utils.PostExperimentals = PostExperimentals;
utils.PostDebug = PostDebug;
%ToFastProperties(utils); %ToFastProperties(utils);
......
This diff is collapsed.
...@@ -17,6 +17,44 @@ ...@@ -17,6 +17,44 @@
namespace v8 { namespace v8 {
namespace internal { 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) { RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
HandleScope scope(isolate); HandleScope scope(isolate);
......
...@@ -63,6 +63,16 @@ namespace internal { ...@@ -63,6 +63,16 @@ namespace internal {
F(ThrowNotIntegerSharedTypedArrayError, 1, 1) \ F(ThrowNotIntegerSharedTypedArrayError, 1, 1) \
F(ThrowNotInt32SharedTypedArrayError, 1, 1) \ F(ThrowNotInt32SharedTypedArrayError, 1, 1) \
F(ThrowInvalidAtomicAccessIndexError, 0, 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(AtomicsNumWaitersForTesting, 2, 1) \
F(SetAllowAtomicsWait, 1, 1) F(SetAllowAtomicsWait, 1, 1)
......
...@@ -17,6 +17,12 @@ FixedArray* NativesCollection<CORE>::GetSourceCache(Heap* heap) { ...@@ -17,6 +17,12 @@ FixedArray* NativesCollection<CORE>::GetSourceCache(Heap* heap) {
} }
template <>
FixedArray* NativesCollection<EXPERIMENTAL>::GetSourceCache(Heap* heap) {
return heap->experimental_natives_source_cache();
}
template <> template <>
FixedArray* NativesCollection<EXTRAS>::GetSourceCache(Heap* heap) { FixedArray* NativesCollection<EXTRAS>::GetSourceCache(Heap* heap) {
return heap->extra_natives_source_cache(); return heap->extra_natives_source_cache();
......
...@@ -151,6 +151,8 @@ void ReadNatives() { ...@@ -151,6 +151,8 @@ void ReadNatives() {
if (natives_blob_ && NativesHolder<CORE>::empty()) { if (natives_blob_ && NativesHolder<CORE>::empty()) {
SnapshotByteSource bytes(natives_blob_->data, natives_blob_->raw_size); SnapshotByteSource bytes(natives_blob_->data, natives_blob_->raw_size);
NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes)); NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
NativesHolder<EXPERIMENTAL>::set(
NativesStore::MakeFromScriptsSource(&bytes));
NativesHolder<EXTRAS>::set(NativesStore::MakeFromScriptsSource(&bytes)); NativesHolder<EXTRAS>::set(NativesStore::MakeFromScriptsSource(&bytes));
NativesHolder<EXPERIMENTAL_EXTRAS>::set( NativesHolder<EXPERIMENTAL_EXTRAS>::set(
NativesStore::MakeFromScriptsSource(&bytes)); NativesStore::MakeFromScriptsSource(&bytes));
...@@ -179,6 +181,7 @@ void SetNativesFromFile(StartupData* natives_blob) { ...@@ -179,6 +181,7 @@ void SetNativesFromFile(StartupData* natives_blob) {
*/ */
void DisposeNatives() { void DisposeNatives() {
NativesHolder<CORE>::Dispose(); NativesHolder<CORE>::Dispose();
NativesHolder<EXPERIMENTAL>::Dispose();
NativesHolder<EXTRAS>::Dispose(); NativesHolder<EXTRAS>::Dispose();
NativesHolder<EXPERIMENTAL_EXTRAS>::Dispose(); NativesHolder<EXPERIMENTAL_EXTRAS>::Dispose();
} }
...@@ -230,6 +233,7 @@ Vector<const char> NativesCollection<type>::GetScriptsSource() { ...@@ -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>::GetScriptName(int i); \
template Vector<const char> NativesCollection<T>::GetScriptsSource(); template Vector<const char> NativesCollection<T>::GetScriptsSource();
INSTANTIATE_TEMPLATES(CORE) INSTANTIATE_TEMPLATES(CORE)
INSTANTIATE_TEMPLATES(EXPERIMENTAL)
INSTANTIATE_TEMPLATES(EXTRAS) INSTANTIATE_TEMPLATES(EXTRAS)
INSTANTIATE_TEMPLATES(EXPERIMENTAL_EXTRAS) INSTANTIATE_TEMPLATES(EXPERIMENTAL_EXTRAS)
#undef INSTANTIATE_TEMPLATES #undef INSTANTIATE_TEMPLATES
......
...@@ -15,6 +15,7 @@ namespace internal { ...@@ -15,6 +15,7 @@ namespace internal {
enum NativeType { enum NativeType {
CORE, CORE,
EXPERIMENTAL,
EXTRAS, EXTRAS,
EXPERIMENTAL_EXTRAS, EXPERIMENTAL_EXTRAS,
D8, D8,
...@@ -53,6 +54,7 @@ class V8_EXPORT_PRIVATE NativesCollection { ...@@ -53,6 +54,7 @@ class V8_EXPORT_PRIVATE NativesCollection {
}; };
typedef NativesCollection<CORE> Natives; typedef NativesCollection<CORE> Natives;
typedef NativesCollection<EXPERIMENTAL> ExperimentalNatives;
typedef NativesCollection<EXTRAS> ExtraNatives; typedef NativesCollection<EXTRAS> ExtraNatives;
typedef NativesCollection<EXPERIMENTAL_EXTRAS> ExperimentalExtraNatives; typedef NativesCollection<EXPERIMENTAL_EXTRAS> ExperimentalExtraNatives;
......
...@@ -171,6 +171,7 @@ ...@@ -171,6 +171,7 @@
], ],
'sources': [ 'sources': [
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
'<(INTERMEDIATE_DIR)/snapshot.cc', '<(INTERMEDIATE_DIR)/snapshot.cc',
...@@ -229,6 +230,7 @@ ...@@ -229,6 +230,7 @@
], ],
'sources': [ 'sources': [
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc',
'<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/experimental-extras-libraries.cc',
'snapshot/snapshot-empty.cc', 'snapshot/snapshot-empty.cc',
...@@ -2204,6 +2206,7 @@ ...@@ -2204,6 +2206,7 @@
'inputs': [ 'inputs': [
'../tools/concatenate-files.py', '../tools/concatenate-files.py',
'<(SHARED_INTERMEDIATE_DIR)/libraries.bin', '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
'<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
'<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin', '<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin',
'<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin', '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin',
], ],
...@@ -2278,7 +2281,13 @@ ...@@ -2278,7 +2281,13 @@
'debug/debug.js', 'debug/debug.js',
'debug/liveedit.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_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_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-extras.bin',
'libraries_experimental_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin', 'libraries_experimental_extras_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental-extras.bin',
'conditions': [ 'conditions': [
...@@ -2320,6 +2329,38 @@ ...@@ -2320,6 +2329,38 @@
'--nojs', '--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', 'action_name': 'js2c_extras',
'inputs': [ 'inputs': [
......
...@@ -530,8 +530,8 @@ TEST(SizeOfInitialHeap) { ...@@ -530,8 +530,8 @@ TEST(SizeOfInitialHeap) {
// requires no extra space. // requires no extra space.
CompileRun("/*empty*/"); CompileRun("/*empty*/");
for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { 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. // Debug code can be very large, so skip CODE_SPACE if we are generating it.
if (i == CODE_SPACE) continue; if (i == CODE_SPACE && i::FLAG_debug_code) continue;
CHECK_EQ(page_count[i], isolate->heap()->paged_space(i)->CountTotalPages()); CHECK_EQ(page_count[i], isolate->heap()->paged_space(i)->CountTotalPages());
} }
......
...@@ -109,14 +109,6 @@ ...@@ -109,14 +109,6 @@
Atomics.wake(i32a, 0, Number.POSITIVE_INFINITY); 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 //// WORKER ONLY TESTS
if (this.Worker) { 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