diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index 337a5531e8a444..69afcfd23e9bdd 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -20,6 +20,7 @@ *.xcodeproj #*# *~ +.#* .cpplint-cache .cproject .d8_history @@ -42,33 +43,20 @@ shell_g /build/gyp /build/ipch/ /build/Release +/build/win_toolchain.json /buildtools /hydrogen.cfg /obj /out /perf.data /perf.data.old -/test/benchmarks/CHECKED_OUT_* -/test/benchmarks/downloaded_* -/test/benchmarks/kraken -/test/benchmarks/octane -/test/benchmarks/sunspider -/test/mozilla/CHECKED_OUT_VERSION +/test/benchmarks/data /test/mozilla/data -/test/mozilla/data.old -/test/mozilla/downloaded_* /test/promises-aplus/promises-tests /test/promises-aplus/promises-tests.tar.gz /test/promises-aplus/sinon -/test/simdjs/CHECKED_OUT_* -/test/simdjs/ecmascript_simd* -/test/simdjs/data* +/test/simdjs/data /test/test262/data -/test/test262/data.old -/test/test262/tc39-test262-* -/test/test262-es6/data -/test/test262-es6/data.old -/test/test262-es6/tc39-test262-* /testing/gmock /testing/gtest /third_party @@ -78,6 +66,9 @@ shell_g /tools/clang /tools/jsfunfuzz /tools/jsfunfuzz.zip +/tools/luci-go/linux64/isolate +/tools/luci-go/mac64/isolate +/tools/luci-go/win64/isolate.exe /tools/oom_dump/oom_dump /tools/oom_dump/oom_dump.o /tools/swarming_client diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 9dfb07328e0c6d..fdef3668bba38a 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -54,6 +54,7 @@ Erich Ocean Fedor Indutny Felix Geisendörfer Filipe David Manana +Franziska Hinkelmann Geoffrey Garside Han Choongwoo Hirofumi Mako @@ -81,6 +82,7 @@ Michael Lutz Michael Smith Mike Gilbert Mike Pennisi +Milton Chiang Nicolas Antonius Ernst Leopold Maria Kaiser Paolo Giarrusso Patrick Gansterer diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 9dfdaa3cdaa393..443ffe1e48e4dc 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -7,12 +7,22 @@ import("//build/config/arm.gni") import("//build/config/mips.gni") import("//build/config/sanitizers/sanitizers.gni") +if (is_android) { + import("//build/config/android/rules.gni") +} + # Because standalone V8 builds are not supported, assume this is part of a # Chromium build. -import("//build/module_args/v8.gni") +import("//build_overrides/v8.gni") import("snapshot_toolchain.gni") +declare_args() { + # Enable the snapshot feature, for fast context creation. + # http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html + v8_use_snapshot = true +} + # TODO(jochen): These will need to be user-settable to support standalone V8 # builds. v8_deprecation_warnings = false @@ -24,7 +34,6 @@ v8_enable_verify_heap = false v8_interpreted_regexp = false v8_object_print = false v8_postmortem_support = false -v8_use_snapshot = true v8_random_seed = "314159265" v8_toolset_for_d8 = "host" @@ -71,6 +80,14 @@ config("external_config") { include_dirs = [ "include" ] } +# This config should only be applied to code that needs to be explicitly +# aware of whether we are using startup data or not. +config("external_startup_data") { + if (v8_use_external_startup_data) { + defines = [ "V8_USE_EXTERNAL_STARTUP_DATA" ] + } +} + config("features") { visibility = [ ":*" ] # Only targets in this file can depend on this. @@ -194,35 +211,34 @@ action("js2c") { inputs = [ "tools/jsmin.py" ] sources = [ - "src/macros.py", + "src/js/macros.py", "src/messages.h", - "src/prologue.js", - "src/runtime.js", - "src/v8natives.js", - "src/symbol.js", - "src/array.js", - "src/string.js", - "src/uri.js", - "src/math.js", + "src/js/prologue.js", + "src/js/runtime.js", + "src/js/v8natives.js", + "src/js/symbol.js", + "src/js/array.js", + "src/js/string.js", + "src/js/uri.js", + "src/js/math.js", "src/third_party/fdlibm/fdlibm.js", - "src/date.js", - "src/regexp.js", - "src/arraybuffer.js", - "src/typedarray.js", - "src/iterator-prototype.js", - "src/generator.js", - "src/object-observe.js", - "src/collection.js", - "src/weak-collection.js", - "src/collection-iterator.js", - "src/promise.js", - "src/messages.js", - "src/json.js", - "src/array-iterator.js", - "src/string-iterator.js", - "src/templates.js", - "src/harmony-array.js", - "src/harmony-typedarray.js", + "src/js/date.js", + "src/js/regexp.js", + "src/js/arraybuffer.js", + "src/js/typedarray.js", + "src/js/iterator-prototype.js", + "src/js/generator.js", + "src/js/object-observe.js", + "src/js/collection.js", + "src/js/weak-collection.js", + "src/js/collection-iterator.js", + "src/js/promise.js", + "src/js/messages.js", + "src/js/json.js", + "src/js/array-iterator.js", + "src/js/string-iterator.js", + "src/js/templates.js", + "src/js/spread.js", "src/debug/mirrors.js", "src/debug/debug.js", "src/debug/liveedit.js", @@ -233,7 +249,7 @@ action("js2c") { ] if (v8_enable_i18n_support) { - sources += [ "src/i18n.js" ] + sources += [ "src/js/i18n.js" ] } args = [ @@ -260,9 +276,9 @@ action("js2c_code_stubs") { inputs = [ "tools/jsmin.py" ] sources = [ - "src/macros.py", + "src/js/macros.py", "src/messages.h", - "src/code-stubs.js" + "src/js/code-stubs.js" ] outputs = [ @@ -294,20 +310,17 @@ action("js2c_experimental") { inputs = [ "tools/jsmin.py" ] sources = [ - "src/macros.py", + "src/js/macros.py", "src/messages.h", - "src/proxy.js", - "src/generator.js", - "src/harmony-atomics.js", - "src/harmony-array-includes.js", - "src/harmony-concat-spreadable.js", - "src/harmony-tostring.js", - "src/harmony-regexp.js", - "src/harmony-reflect.js", - "src/harmony-spread.js", - "src/harmony-object-observe.js", - "src/harmony-sharedarraybuffer.js", - "src/harmony-simd.js" + "src/js/proxy.js", + "src/js/generator.js", + "src/js/harmony-atomics.js", + "src/js/harmony-array-includes.js", + "src/js/harmony-regexp.js", + "src/js/harmony-reflect.js", + "src/js/harmony-object-observe.js", + "src/js/harmony-sharedarraybuffer.js", + "src/js/harmony-simd.js" ] outputs = [ @@ -396,7 +409,7 @@ action("d8_js2c") { inputs = [ "src/d8.js", - "src/macros.py", + "src/js/macros.py", ] outputs = [ @@ -407,6 +420,19 @@ action("d8_js2c") { rebase_path(inputs, root_build_dir) } +if (is_android) { + android_assets("v8_external_startup_data_assets") { + if (v8_use_external_startup_data) { + deps = [ + "//v8", + ] + renaming_sources = v8_external_startup_data_renaming_sources + renaming_destinations = v8_external_startup_data_renaming_destinations + disable_compression = true + } + } +} + if (v8_use_external_startup_data) { action("natives_blob") { visibility = [ ":*" ] # Only targets in this file can depend on this. @@ -620,6 +646,8 @@ source_set("v8_base") { "include/v8config.h", "src/accessors.cc", "src/accessors.h", + "src/address-map.cc", + "src/address-map.h", "src/allocation.cc", "src/allocation.h", "src/allocation-site-scopes.cc", @@ -684,6 +712,8 @@ source_set("v8_base") { "src/compilation-statistics.h", "src/compiler/access-builder.cc", "src/compiler/access-builder.h", + "src/compiler/access-info.cc", + "src/compiler/access-info.h", "src/compiler/all-nodes.cc", "src/compiler/all-nodes.h", "src/compiler/ast-graph-builder.cc", @@ -692,6 +722,10 @@ source_set("v8_base") { "src/compiler/ast-loop-assignment-analyzer.h", "src/compiler/basic-block-instrumentor.cc", "src/compiler/basic-block-instrumentor.h", + "src/compiler/binary-operator-reducer.cc", + "src/compiler/binary-operator-reducer.h", + "src/compiler/branch-elimination.cc", + "src/compiler/branch-elimination.h", "src/compiler/bytecode-graph-builder.cc", "src/compiler/bytecode-graph-builder.h", "src/compiler/change-lowering.cc", @@ -755,18 +789,20 @@ source_set("v8_base") { "src/compiler/js-frame-specialization.h", "src/compiler/js-generic-lowering.cc", "src/compiler/js-generic-lowering.h", + "src/compiler/js-global-object-specialization.cc", + "src/compiler/js-global-object-specialization.h", "src/compiler/js-graph.cc", "src/compiler/js-graph.h", "src/compiler/js-inlining.cc", "src/compiler/js-inlining.h", + "src/compiler/js-inlining-heuristic.cc", + "src/compiler/js-inlining-heuristic.h", "src/compiler/js-intrinsic-lowering.cc", "src/compiler/js-intrinsic-lowering.h", + "src/compiler/js-native-context-specialization.cc", + "src/compiler/js-native-context-specialization.h", "src/compiler/js-operator.cc", "src/compiler/js-operator.h", - "src/compiler/js-type-feedback.cc", - "src/compiler/js-type-feedback.h", - "src/compiler/js-type-feedback-lowering.cc", - "src/compiler/js-type-feedback-lowering.h", "src/compiler/js-typed-lowering.cc", "src/compiler/js-typed-lowering.h", "src/compiler/jump-threading.cc", @@ -819,8 +855,6 @@ source_set("v8_base") { "src/compiler/register-allocator.h", "src/compiler/register-allocator-verifier.cc", "src/compiler/register-allocator-verifier.h", - "src/compiler/register-configuration.cc", - "src/compiler/register-configuration.h", "src/compiler/representation-change.h", "src/compiler/schedule.cc", "src/compiler/schedule.h", @@ -860,6 +894,68 @@ source_set("v8_base") { "src/conversions.h", "src/counters.cc", "src/counters.h", + "src/crankshaft/hydrogen-alias-analysis.h", + "src/crankshaft/hydrogen-bce.cc", + "src/crankshaft/hydrogen-bce.h", + "src/crankshaft/hydrogen-bch.cc", + "src/crankshaft/hydrogen-bch.h", + "src/crankshaft/hydrogen-canonicalize.cc", + "src/crankshaft/hydrogen-canonicalize.h", + "src/crankshaft/hydrogen-check-elimination.cc", + "src/crankshaft/hydrogen-check-elimination.h", + "src/crankshaft/hydrogen-dce.cc", + "src/crankshaft/hydrogen-dce.h", + "src/crankshaft/hydrogen-dehoist.cc", + "src/crankshaft/hydrogen-dehoist.h", + "src/crankshaft/hydrogen-environment-liveness.cc", + "src/crankshaft/hydrogen-environment-liveness.h", + "src/crankshaft/hydrogen-escape-analysis.cc", + "src/crankshaft/hydrogen-escape-analysis.h", + "src/crankshaft/hydrogen-flow-engine.h", + "src/crankshaft/hydrogen-gvn.cc", + "src/crankshaft/hydrogen-gvn.h", + "src/crankshaft/hydrogen-infer-representation.cc", + "src/crankshaft/hydrogen-infer-representation.h", + "src/crankshaft/hydrogen-infer-types.cc", + "src/crankshaft/hydrogen-infer-types.h", + "src/crankshaft/hydrogen-instructions.cc", + "src/crankshaft/hydrogen-instructions.h", + "src/crankshaft/hydrogen-load-elimination.cc", + "src/crankshaft/hydrogen-load-elimination.h", + "src/crankshaft/hydrogen-mark-deoptimize.cc", + "src/crankshaft/hydrogen-mark-deoptimize.h", + "src/crankshaft/hydrogen-mark-unreachable.cc", + "src/crankshaft/hydrogen-mark-unreachable.h", + "src/crankshaft/hydrogen-osr.cc", + "src/crankshaft/hydrogen-osr.h", + "src/crankshaft/hydrogen-range-analysis.cc", + "src/crankshaft/hydrogen-range-analysis.h", + "src/crankshaft/hydrogen-redundant-phi.cc", + "src/crankshaft/hydrogen-redundant-phi.h", + "src/crankshaft/hydrogen-removable-simulates.cc", + "src/crankshaft/hydrogen-removable-simulates.h", + "src/crankshaft/hydrogen-representation-changes.cc", + "src/crankshaft/hydrogen-representation-changes.h", + "src/crankshaft/hydrogen-sce.cc", + "src/crankshaft/hydrogen-sce.h", + "src/crankshaft/hydrogen-store-elimination.cc", + "src/crankshaft/hydrogen-store-elimination.h", + "src/crankshaft/hydrogen-types.cc", + "src/crankshaft/hydrogen-types.h", + "src/crankshaft/hydrogen-uint32-analysis.cc", + "src/crankshaft/hydrogen-uint32-analysis.h", + "src/crankshaft/hydrogen.cc", + "src/crankshaft/hydrogen.h", + "src/crankshaft/lithium-allocator-inl.h", + "src/crankshaft/lithium-allocator.cc", + "src/crankshaft/lithium-allocator.h", + "src/crankshaft/lithium-codegen.cc", + "src/crankshaft/lithium-codegen.h", + "src/crankshaft/lithium.cc", + "src/crankshaft/lithium.h", + "src/crankshaft/typing.cc", + "src/crankshaft/typing.h", + "src/crankshaft/unique.h", "src/date.cc", "src/date.h", "src/dateparser-inl.h", @@ -968,58 +1064,6 @@ source_set("v8_base") { "src/heap/store-buffer-inl.h", "src/heap/store-buffer.cc", "src/heap/store-buffer.h", - "src/hydrogen-alias-analysis.h", - "src/hydrogen-bce.cc", - "src/hydrogen-bce.h", - "src/hydrogen-bch.cc", - "src/hydrogen-bch.h", - "src/hydrogen-canonicalize.cc", - "src/hydrogen-canonicalize.h", - "src/hydrogen-check-elimination.cc", - "src/hydrogen-check-elimination.h", - "src/hydrogen-dce.cc", - "src/hydrogen-dce.h", - "src/hydrogen-dehoist.cc", - "src/hydrogen-dehoist.h", - "src/hydrogen-environment-liveness.cc", - "src/hydrogen-environment-liveness.h", - "src/hydrogen-escape-analysis.cc", - "src/hydrogen-escape-analysis.h", - "src/hydrogen-flow-engine.h", - "src/hydrogen-instructions.cc", - "src/hydrogen-instructions.h", - "src/hydrogen.cc", - "src/hydrogen.h", - "src/hydrogen-gvn.cc", - "src/hydrogen-gvn.h", - "src/hydrogen-infer-representation.cc", - "src/hydrogen-infer-representation.h", - "src/hydrogen-infer-types.cc", - "src/hydrogen-infer-types.h", - "src/hydrogen-load-elimination.cc", - "src/hydrogen-load-elimination.h", - "src/hydrogen-mark-deoptimize.cc", - "src/hydrogen-mark-deoptimize.h", - "src/hydrogen-mark-unreachable.cc", - "src/hydrogen-mark-unreachable.h", - "src/hydrogen-osr.cc", - "src/hydrogen-osr.h", - "src/hydrogen-range-analysis.cc", - "src/hydrogen-range-analysis.h", - "src/hydrogen-redundant-phi.cc", - "src/hydrogen-redundant-phi.h", - "src/hydrogen-removable-simulates.cc", - "src/hydrogen-removable-simulates.h", - "src/hydrogen-representation-changes.cc", - "src/hydrogen-representation-changes.h", - "src/hydrogen-sce.cc", - "src/hydrogen-sce.h", - "src/hydrogen-store-elimination.cc", - "src/hydrogen-store-elimination.h", - "src/hydrogen-types.cc", - "src/hydrogen-types.h", - "src/hydrogen-uint32-analysis.cc", - "src/hydrogen-uint32-analysis.h", "src/i18n.cc", "src/i18n.h", "src/icu_util.cc", @@ -1051,6 +1095,9 @@ source_set("v8_base") { "src/interpreter/bytecode-array-iterator.h", "src/interpreter/bytecode-generator.cc", "src/interpreter/bytecode-generator.h", + "src/interpreter/bytecode-traits.h", + "src/interpreter/control-flow-builders.cc", + "src/interpreter/control-flow-builders.h", "src/interpreter/interpreter.cc", "src/interpreter/interpreter.h", "src/isolate-inl.h", @@ -1058,24 +1105,18 @@ source_set("v8_base") { "src/isolate.h", "src/json-parser.h", "src/json-stringifier.h", + "src/key-accumulator.h", + "src/key-accumulator.cc", "src/layout-descriptor-inl.h", "src/layout-descriptor.cc", "src/layout-descriptor.h", "src/list-inl.h", "src/list.h", - "src/lithium-allocator-inl.h", - "src/lithium-allocator.cc", - "src/lithium-allocator.h", - "src/lithium-codegen.cc", - "src/lithium-codegen.h", - "src/lithium.cc", - "src/lithium.h", "src/log-inl.h", "src/log-utils.cc", "src/log-utils.h", "src/log.cc", "src/log.h", - "src/lookup-inl.h", "src/lookup.cc", "src/lookup.h", "src/macro-assembler.h", @@ -1093,9 +1134,11 @@ source_set("v8_base") { "src/optimizing-compile-dispatcher.h", "src/ostreams.cc", "src/ostreams.h", - "src/pattern-rewriter.cc", + "src/parameter-initializer-rewriter.cc", + "src/parameter-initializer-rewriter.h", "src/parser.cc", "src/parser.h", + "src/pattern-rewriter.cc", "src/pending-compilation-error-handler.cc", "src/pending-compilation-error-handler.h", "src/preparse-data-format.h", @@ -1122,8 +1165,12 @@ source_set("v8_base") { "src/profiler/profile-generator.h", "src/profiler/sampler.cc", "src/profiler/sampler.h", + "src/profiler/strings-storage.cc", + "src/profiler/strings-storage.h", "src/profiler/unbound-queue-inl.h", "src/profiler/unbound-queue.h", + "src/property-descriptor.cc", + "src/property-descriptor.h", "src/property-details.h", "src/property.cc", "src/property.h", @@ -1145,6 +1192,8 @@ source_set("v8_base") { "src/regexp/regexp-macro-assembler.h", "src/regexp/regexp-stack.cc", "src/regexp/regexp-stack.h", + "src/register-configuration.cc", + "src/register-configuration.h", "src/runtime-profiler.cc", "src/runtime-profiler.h", "src/runtime/runtime-array.cc", @@ -1211,8 +1260,6 @@ source_set("v8_base") { "src/string-search.h", "src/string-stream.cc", "src/string-stream.h", - "src/strings-storage.cc", - "src/strings-storage.h", "src/strtod.cc", "src/strtod.h", "src/token.cc", @@ -1220,6 +1267,8 @@ source_set("v8_base") { "src/transitions-inl.h", "src/transitions.cc", "src/transitions.h", + "src/type-cache.cc", + "src/type-cache.h", "src/type-feedback-vector-inl.h", "src/type-feedback-vector.cc", "src/type-feedback-vector.h", @@ -1232,8 +1281,6 @@ source_set("v8_base") { "src/typing-asm.h", "src/typing-reset.cc", "src/typing-reset.h", - "src/typing.cc", - "src/typing.h", "src/unicode-inl.h", "src/unicode.cc", "src/unicode.h", @@ -1241,7 +1288,6 @@ source_set("v8_base") { "src/unicode-cache.h", "src/unicode-decoder.cc", "src/unicode-decoder.h", - "src/unique.h", "src/utils.cc", "src/utils.h", "src/v8.cc", @@ -1255,7 +1301,6 @@ source_set("v8_base") { "src/version.h", "src/vm-state-inl.h", "src/vm-state.h", - "src/zone-type-cache.h", "src/zone.cc", "src/zone.h", "src/zone-allocator.h", @@ -1266,6 +1311,17 @@ source_set("v8_base") { if (v8_target_arch == "x86") { sources += [ + "src/crankshaft/ia32/lithium-codegen-ia32.cc", + "src/crankshaft/ia32/lithium-codegen-ia32.h", + "src/crankshaft/ia32/lithium-gap-resolver-ia32.cc", + "src/crankshaft/ia32/lithium-gap-resolver-ia32.h", + "src/crankshaft/ia32/lithium-ia32.cc", + "src/crankshaft/ia32/lithium-ia32.h", + "src/compiler/ia32/code-generator-ia32.cc", + "src/compiler/ia32/instruction-codes-ia32.h", + "src/compiler/ia32/instruction-selector-ia32.cc", + "src/debug/ia32/debug-ia32.cc", + "src/full-codegen/ia32/full-codegen-ia32.cc", "src/ia32/assembler-ia32-inl.h", "src/ia32/assembler-ia32.cc", "src/ia32/assembler-ia32.h", @@ -1280,19 +1336,8 @@ source_set("v8_base") { "src/ia32/frames-ia32.cc", "src/ia32/frames-ia32.h", "src/ia32/interface-descriptors-ia32.cc", - "src/ia32/lithium-codegen-ia32.cc", - "src/ia32/lithium-codegen-ia32.h", - "src/ia32/lithium-gap-resolver-ia32.cc", - "src/ia32/lithium-gap-resolver-ia32.h", - "src/ia32/lithium-ia32.cc", - "src/ia32/lithium-ia32.h", "src/ia32/macro-assembler-ia32.cc", "src/ia32/macro-assembler-ia32.h", - "src/compiler/ia32/code-generator-ia32.cc", - "src/compiler/ia32/instruction-codes-ia32.h", - "src/compiler/ia32/instruction-selector-ia32.cc", - "src/debug/ia32/debug-ia32.cc", - "src/full-codegen/ia32/full-codegen-ia32.cc", "src/ic/ia32/access-compiler-ia32.cc", "src/ic/ia32/handler-compiler-ia32.cc", "src/ic/ia32/ic-ia32.cc", @@ -1303,6 +1348,24 @@ source_set("v8_base") { ] } else if (v8_target_arch == "x64") { sources += [ + "src/compiler/x64/code-generator-x64.cc", + "src/compiler/x64/instruction-codes-x64.h", + "src/compiler/x64/instruction-selector-x64.cc", + "src/crankshaft/x64/lithium-codegen-x64.cc", + "src/crankshaft/x64/lithium-codegen-x64.h", + "src/crankshaft/x64/lithium-gap-resolver-x64.cc", + "src/crankshaft/x64/lithium-gap-resolver-x64.h", + "src/crankshaft/x64/lithium-x64.cc", + "src/crankshaft/x64/lithium-x64.h", + "src/debug/x64/debug-x64.cc", + "src/full-codegen/x64/full-codegen-x64.cc", + "src/ic/x64/access-compiler-x64.cc", + "src/ic/x64/handler-compiler-x64.cc", + "src/ic/x64/ic-x64.cc", + "src/ic/x64/ic-compiler-x64.cc", + "src/ic/x64/stub-cache-x64.cc", + "src/regexp/x64/regexp-macro-assembler-x64.cc", + "src/regexp/x64/regexp-macro-assembler-x64.h", "src/x64/assembler-x64-inl.h", "src/x64/assembler-x64.cc", "src/x64/assembler-x64.h", @@ -1317,26 +1380,8 @@ source_set("v8_base") { "src/x64/frames-x64.cc", "src/x64/frames-x64.h", "src/x64/interface-descriptors-x64.cc", - "src/x64/lithium-codegen-x64.cc", - "src/x64/lithium-codegen-x64.h", - "src/x64/lithium-gap-resolver-x64.cc", - "src/x64/lithium-gap-resolver-x64.h", - "src/x64/lithium-x64.cc", - "src/x64/lithium-x64.h", "src/x64/macro-assembler-x64.cc", "src/x64/macro-assembler-x64.h", - "src/compiler/x64/code-generator-x64.cc", - "src/compiler/x64/instruction-codes-x64.h", - "src/compiler/x64/instruction-selector-x64.cc", - "src/debug/x64/debug-x64.cc", - "src/full-codegen/x64/full-codegen-x64.cc", - "src/ic/x64/access-compiler-x64.cc", - "src/ic/x64/handler-compiler-x64.cc", - "src/ic/x64/ic-x64.cc", - "src/ic/x64/ic-compiler-x64.cc", - "src/ic/x64/stub-cache-x64.cc", - "src/regexp/x64/regexp-macro-assembler-x64.cc", - "src/regexp/x64/regexp-macro-assembler-x64.h", ] } else if (v8_target_arch == "arm") { sources += [ @@ -1357,12 +1402,6 @@ source_set("v8_base") { "src/arm/frames-arm.h", "src/arm/interface-descriptors-arm.cc", "src/arm/interface-descriptors-arm.h", - "src/arm/lithium-arm.cc", - "src/arm/lithium-arm.h", - "src/arm/lithium-codegen-arm.cc", - "src/arm/lithium-codegen-arm.h", - "src/arm/lithium-gap-resolver-arm.cc", - "src/arm/lithium-gap-resolver-arm.h", "src/arm/macro-assembler-arm.cc", "src/arm/macro-assembler-arm.h", "src/arm/simulator-arm.cc", @@ -1370,6 +1409,12 @@ source_set("v8_base") { "src/compiler/arm/code-generator-arm.cc", "src/compiler/arm/instruction-codes-arm.h", "src/compiler/arm/instruction-selector-arm.cc", + "src/crankshaft/arm/lithium-arm.cc", + "src/crankshaft/arm/lithium-arm.h", + "src/crankshaft/arm/lithium-codegen-arm.cc", + "src/crankshaft/arm/lithium-codegen-arm.h", + "src/crankshaft/arm/lithium-gap-resolver-arm.cc", + "src/crankshaft/arm/lithium-gap-resolver-arm.h", "src/debug/arm/debug-arm.cc", "src/full-codegen/arm/full-codegen-arm.cc", "src/ic/arm/access-compiler-arm.cc", @@ -1395,9 +1440,6 @@ source_set("v8_base") { "src/arm64/decoder-arm64.cc", "src/arm64/decoder-arm64.h", "src/arm64/decoder-arm64-inl.h", - "src/arm64/delayed-masm-arm64.cc", - "src/arm64/delayed-masm-arm64.h", - "src/arm64/delayed-masm-arm64-inl.h", "src/arm64/deoptimizer-arm64.cc", "src/arm64/disasm-arm64.cc", "src/arm64/disasm-arm64.h", @@ -1409,12 +1451,6 @@ source_set("v8_base") { "src/arm64/instrument-arm64.h", "src/arm64/interface-descriptors-arm64.cc", "src/arm64/interface-descriptors-arm64.h", - "src/arm64/lithium-arm64.cc", - "src/arm64/lithium-arm64.h", - "src/arm64/lithium-codegen-arm64.cc", - "src/arm64/lithium-codegen-arm64.h", - "src/arm64/lithium-gap-resolver-arm64.cc", - "src/arm64/lithium-gap-resolver-arm64.h", "src/arm64/macro-assembler-arm64.cc", "src/arm64/macro-assembler-arm64.h", "src/arm64/macro-assembler-arm64-inl.h", @@ -1425,6 +1461,15 @@ source_set("v8_base") { "src/compiler/arm64/code-generator-arm64.cc", "src/compiler/arm64/instruction-codes-arm64.h", "src/compiler/arm64/instruction-selector-arm64.cc", + "src/crankshaft/arm64/delayed-masm-arm64.cc", + "src/crankshaft/arm64/delayed-masm-arm64.h", + "src/crankshaft/arm64/delayed-masm-arm64-inl.h", + "src/crankshaft/arm64/lithium-arm64.cc", + "src/crankshaft/arm64/lithium-arm64.h", + "src/crankshaft/arm64/lithium-codegen-arm64.cc", + "src/crankshaft/arm64/lithium-codegen-arm64.h", + "src/crankshaft/arm64/lithium-gap-resolver-arm64.cc", + "src/crankshaft/arm64/lithium-gap-resolver-arm64.h", "src/debug/arm64/debug-arm64.cc", "src/full-codegen/arm64/full-codegen-arm64.cc", "src/ic/arm64/access-compiler-arm64.cc", @@ -1437,6 +1482,22 @@ source_set("v8_base") { ] } else if (v8_target_arch == "mipsel") { sources += [ + "src/compiler/mips/code-generator-mips.cc", + "src/compiler/mips/instruction-codes-mips.h", + "src/compiler/mips/instruction-selector-mips.cc", + "src/crankshaft/mips/lithium-codegen-mips.cc", + "src/crankshaft/mips/lithium-codegen-mips.h", + "src/crankshaft/mips/lithium-gap-resolver-mips.cc", + "src/crankshaft/mips/lithium-gap-resolver-mips.h", + "src/crankshaft/mips/lithium-mips.cc", + "src/crankshaft/mips/lithium-mips.h", + "src/debug/mips/debug-mips.cc", + "src/full-codegen/mips/full-codegen-mips.cc", + "src/ic/mips/access-compiler-mips.cc", + "src/ic/mips/handler-compiler-mips.cc", + "src/ic/mips/ic-mips.cc", + "src/ic/mips/ic-compiler-mips.cc", + "src/ic/mips/stub-cache-mips.cc", "src/mips/assembler-mips.cc", "src/mips/assembler-mips.h", "src/mips/assembler-mips-inl.h", @@ -1453,31 +1514,31 @@ source_set("v8_base") { "src/mips/frames-mips.cc", "src/mips/frames-mips.h", "src/mips/interface-descriptors-mips.cc", - "src/mips/lithium-codegen-mips.cc", - "src/mips/lithium-codegen-mips.h", - "src/mips/lithium-gap-resolver-mips.cc", - "src/mips/lithium-gap-resolver-mips.h", - "src/mips/lithium-mips.cc", - "src/mips/lithium-mips.h", "src/mips/macro-assembler-mips.cc", "src/mips/macro-assembler-mips.h", "src/mips/simulator-mips.cc", "src/mips/simulator-mips.h", - "src/compiler/mips/code-generator-mips.cc", - "src/compiler/mips/instruction-codes-mips.h", - "src/compiler/mips/instruction-selector-mips.cc", - "src/debug/mips/debug-mips.cc", - "src/full-codegen/mips/full-codegen-mips.cc", - "src/ic/mips/access-compiler-mips.cc", - "src/ic/mips/handler-compiler-mips.cc", - "src/ic/mips/ic-mips.cc", - "src/ic/mips/ic-compiler-mips.cc", - "src/ic/mips/stub-cache-mips.cc", "src/regexp/mips/regexp-macro-assembler-mips.cc", "src/regexp/mips/regexp-macro-assembler-mips.h", ] } else if (v8_target_arch == "mips64el") { sources += [ + "compiler/mips64/code-generator-mips64.cc", + "compiler/mips64/instruction-codes-mips64.h", + "compiler/mips64/instruction-selector-mips64.cc", + "src/crankshaft/mips64/lithium-codegen-mips64.cc", + "src/crankshaft/mips64/lithium-codegen-mips64.h", + "src/crankshaft/mips64/lithium-gap-resolver-mips64.cc", + "src/crankshaft/mips64/lithium-gap-resolver-mips64.h", + "src/crankshaft/mips64/lithium-mips64.cc", + "src/crankshaft/mips64/lithium-mips64.h", + "src/debug/mips64/debug-mips64.cc", + "src/full-codegen/mips64/full-codegen-mips64.cc", + "src/ic/mips64/access-compiler-mips64.cc", + "src/ic/mips64/handler-compiler-mips64.cc", + "src/ic/mips64/ic-mips64.cc", + "src/ic/mips64/ic-compiler-mips64.cc", + "src/ic/mips64/stub-cache-mips64.cc", "src/mips64/assembler-mips64.cc", "src/mips64/assembler-mips64.h", "src/mips64/assembler-mips64-inl.h", @@ -1494,23 +1555,10 @@ source_set("v8_base") { "src/mips64/frames-mips64.cc", "src/mips64/frames-mips64.h", "src/mips64/interface-descriptors-mips64.cc", - "src/mips64/lithium-codegen-mips64.cc", - "src/mips64/lithium-codegen-mips64.h", - "src/mips64/lithium-gap-resolver-mips64.cc", - "src/mips64/lithium-gap-resolver-mips64.h", - "src/mips64/lithium-mips64.cc", - "src/mips64/lithium-mips64.h", "src/mips64/macro-assembler-mips64.cc", "src/mips64/macro-assembler-mips64.h", "src/mips64/simulator-mips64.cc", "src/mips64/simulator-mips64.h", - "src/debug/mips64/debug-mips64.cc", - "src/full-codegen/mips64/full-codegen-mips64.cc", - "src/ic/mips64/access-compiler-mips64.cc", - "src/ic/mips64/handler-compiler-mips64.cc", - "src/ic/mips64/ic-mips64.cc", - "src/ic/mips64/ic-compiler-mips64.cc", - "src/ic/mips64/stub-cache-mips64.cc", "src/regexp/mips64/regexp-macro-assembler-mips64.cc", "src/regexp/mips64/regexp-macro-assembler-mips64.h", ] diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 3c6e5d8850b754..4311545a5a79c8 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,1499 @@ +2015-11-11: Version 4.8.271 + + Performance and stability improvements on all platforms. + + +2015-11-11: Version 4.8.270 + + Performance and stability improvements on all platforms. + + +2015-11-11: Version 4.8.269 + + Performance and stability improvements on all platforms. + + +2015-11-10: Version 4.8.268 + + Make JSFunction::BodyDescriptor the only single place that knows how to + iterate JSFunction's body (issue 4531). + + Performance and stability improvements on all platforms. + + +2015-11-10: Version 4.8.267 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.266 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.265 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.264 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.263 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.262 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.261 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.260 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.259 + + Performance and stability improvements on all platforms. + + +2015-11-09: Version 4.8.258 + + Performance and stability improvements on all platforms. + + +2015-11-07: Version 4.8.257 + + Update v8_external_startup_data_assets for + https://codereview.chromium.org/1422793004/ (Chromium issue 547162). + + Performance and stability improvements on all platforms. + + +2015-11-07: Version 4.8.256 + + Performance and stability improvements on all platforms. + + +2015-11-07: Version 4.8.255 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.254 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.253 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.252 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.251 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.250 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.249 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.248 + + Performance and stability improvements on all platforms. + + +2015-11-06: Version 4.8.247 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.246 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.245 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.244 + + Re-ship @@toStringTag (issue 3502). + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.243 + + Stage --harmony-destructuring and --harmony-default-parameters (issues + 811, 2160). + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.242 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.241 + + Re-re-land "[es6] Implement destructuring binding in try/catch" (issue + 811). + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.240 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.239 + + Add v8_external_startup_data GN rule (Chromium issue 547162). + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.238 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.237 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.236 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.235 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.234 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.233 + + Implement flag and source getters on RegExp.prototype (issues 3715, + 4528). + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.232 + + Performance and stability improvements on all platforms. + + +2015-11-05: Version 4.8.231 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.230 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.229 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.228 + + Ship Harmony ToLength (issue 3087). + + Avoid creating indexed elements at index maxUint32 (issue 4516). + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.227 + + Implement flag and source getters on RegExp.prototype (issues 3715, + 4528). + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.226 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.225 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.224 + + [es6] Implement destructuring binding in try/catch (issue 811). + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.223 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.222 + + Implement flag and source getters on RegExp.prototype (issues 3715, + 4528). + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.221 + + Implement flag and source getters on RegExp.prototype (issues 3715, + 4528). + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.220 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.219 + + Performance and stability improvements on all platforms. + + +2015-11-04: Version 4.8.218 + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.217 + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.216 + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.215 + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.214 + + [es6] Fix Object built-in subclassing (issue 3886). + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.213 + + [es6] Fix WeakMap/Set built-ins subclasssing (issues 3101, 3330). + + Reland "[es6] Fix Function and GeneratorFunction built-ins subclassing." + (issues 3101, 3330). + + Implement flag and source getters on RegExp.prototype (issues 3715, + 4528). + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.212 + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.211 + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.210 + + For now, don't assume failed-access-check callback to throw (Chromium + issue 548194). + + Performance and stability improvements on all platforms. + + +2015-11-03: Version 4.8.209 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.208 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.207 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.206 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.205 + + Mark GetCallingContext as soon-to-be deprecated (Chromium issue 541703). + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.204 + + Add boolean to tell if V8 zaps allocated memory (Chromium issue 546492). + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.203 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.202 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.201 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.200 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.199 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.198 + + [es6] Fix Function and GeneratorFunction built-ins subclassing (issues + 3101, 3330). + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.197 + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.196 + + Reland "[es6] Better support for built-ins subclassing." (issues 3101, + 3330, 4419). + + Performance and stability improvements on all platforms. + + +2015-11-02: Version 4.8.195 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.194 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.193 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.192 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.191 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.190 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.189 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.188 + + [es6] Better support for built-ins subclassing (issues 3101, 3330). + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.187 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.186 + + Performance and stability improvements on all platforms. + + +2015-10-30: Version 4.8.185 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.184 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.183 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.182 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.181 + + Reland v8::Private and related APIs. + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.180 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.179 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.178 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.177 + + Performance and stability improvements on all platforms. + + +2015-10-29: Version 4.8.176 + + Stage ES2015 ToLength semantics (issues 3087, 4244). + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.175 + + Avoid calling %AddElement with a number out of array index range (issue + 4516). + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.174 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.173 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.172 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.171 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.170 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.169 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.168 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.167 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.166 + + Performance and stability improvements on all platforms. + + +2015-10-28: Version 4.8.165 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.164 + + Update to ES2015 == semantics for Symbol/SIMD wrappers (issue 3593). + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.163 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.162 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.161 + + Fix deoptimization at ForInStatement::BodyId() (issue 4381). + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.160 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.159 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.158 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.157 + + Performance and stability improvements on all platforms. + + +2015-10-27: Version 4.8.156 + + Check that array length stays a safe integer in Array.prototype.push + (issue 3087). + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.155 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.154 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.153 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.152 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.151 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.150 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.149 + + Performance and stability improvements on all platforms. + + +2015-10-26: Version 4.8.148 + + Performance and stability improvements on all platforms. + + +2015-10-25: Version 4.8.147 + + Performance and stability improvements on all platforms. + + +2015-10-25: Version 4.8.146 + + Performance and stability improvements on all platforms. + + +2015-10-24: Version 4.8.145 + + Performance and stability improvements on all platforms. + + +2015-10-24: Version 4.8.144 + + Performance and stability improvements on all platforms. + + +2015-10-24: Version 4.8.143 + + Performance and stability improvements on all platforms. + + +2015-10-24: Version 4.8.142 + + Performance and stability improvements on all platforms. + + +2015-10-23: Version 4.8.141 + + Stage ES2015-style const in sloppy mode (issue 3739). + + Map v8::Function to JSReceiver + IsCallable. + + Performance and stability improvements on all platforms. + + +2015-10-23: Version 4.8.140 + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.139 + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.138 + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.137 + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.136 + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.135 + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.134 + + [es6] stage sticky regexps and RegExp.prototype.flags (issue 4342). + + [Crankshaft] Don't do HMathFloorOfDiv optimization for kUint32 values + (issue 4507). + + Fix user options for fractional digits in Intl.NumberFormatter (Chromium + issue 544122). + + Performance and stability improvements on all platforms. + + +2015-10-22: Version 4.8.133 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.132 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.131 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.130 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.129 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.128 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.127 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.126 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.125 + + [es6] Handle super properly when rewriting arrow parameter initializers + (issue 4395). + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.124 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.123 + + [es6] Fix scoping for default parameters in arrow functions (issue + 4395). + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.122 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.121 + + Performance and stability improvements on all platforms. + + +2015-10-21: Version 4.8.120 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.119 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.118 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.117 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.116 + + Refactor array construction for map, filter (Chromium issue 544991). + + [es6] Fix scoping for default parameters in arrow functions (issue + 4395). + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.115 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.114 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.113 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.112 + + Performance and stability improvements on all platforms. + + +2015-10-20: Version 4.8.111 + + [es6] stage sticky regexps and RegExp.prototype.flags (issue 4342). + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.110 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.109 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.108 + + ll_prof: Do not use the deprecated tempfile.mktemp() (issue 1306). + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.107 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.106 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.105 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.104 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.103 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.102 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.101 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.100 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.99 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.98 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.97 + + Performance and stability improvements on all platforms. + + +2015-10-19: Version 4.8.96 + + Performance and stability improvements on all platforms. + + +2015-10-18: Version 4.8.95 + + Performance and stability improvements on all platforms. + + +2015-10-18: Version 4.8.94 + + Performance and stability improvements on all platforms. + + +2015-10-18: Version 4.8.93 + + Performance and stability improvements on all platforms. + + +2015-10-17: Version 4.8.92 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.91 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.90 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.89 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.88 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.87 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.86 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.85 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.84 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.83 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.82 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.81 + + Performance and stability improvements on all platforms. + + +2015-10-16: Version 4.8.80 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.79 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.78 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.77 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.76 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.75 + + Make RegExp use ToLength on lastIndex when flag is turned on (issue + 4244). + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.74 + + Take Symbol-keyed properties into account in Object.freeze and friends + (Chromium issue 539875). + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.73 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.72 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.71 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.70 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.69 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.68 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.67 + + Performance and stability improvements on all platforms. + + +2015-10-15: Version 4.8.66 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.65 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.64 + + Add methods to extras' InternalPackedArray (issue 4276). + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.63 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.62 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.61 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.60 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.59 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.58 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.57 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.56 + + Performance and stability improvements on all platforms. + + +2015-10-14: Version 4.8.55 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.54 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.53 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.52 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.51 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.50 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.49 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.48 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.47 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.46 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.45 + + Performance and stability improvements on all platforms. + + +2015-10-13: Version 4.8.44 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.43 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.42 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.41 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.40 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.39 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.38 + + Test for var declarations in eval which conflict with let (issue 4454). + + Don't compile functions in a context the caller doesn't have access to + (Chromium issue 541703). + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.37 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.36 + + Performance and stability improvements on all platforms. + + +2015-10-12: Version 4.8.35 + + Performance and stability improvements on all platforms. + + +2015-10-11: Version 4.8.34 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.33 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.32 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.31 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.30 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.29 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.28 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.27 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.26 + + Performance and stability improvements on all platforms. + + +2015-10-09: Version 4.8.25 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.24 + + Stage --harmony_sloppy_function (issue 4285). + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.23 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.22 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.21 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.20 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.19 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.18 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.17 + + Performance and stability improvements on all platforms. + + +2015-10-08: Version 4.8.16 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.15 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.14 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.13 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.12 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.11 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.10 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.9 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.8 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.7 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.6 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.5 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.4 + + Performance and stability improvements on all platforms. + + +2015-10-07: Version 4.8.3 + + Destructuring array without initializer throws an exception (issue + 4462). + + Disable VirtualAlloc randomization on 32-bit Windows hosts (Chromium + issue 394591). + + Performance and stability improvements on all platforms. + + +2015-10-06: Version 4.8.2 + + Fix legacy const for-of/in destructuring (issue 4461). + + [es6] Align Promise.resolve with the spec (issues 4161, 4341). + + Prohibit let in lexical bindings (issue 4403). + + Ensure scopes are backed by blocks in the body of for loops (Chromium + issues 536750, 536751). + + Performance and stability improvements on all platforms. + + +2015-10-04: Version 4.8.1 + + [cross-context] create new function prototypes in the context of the + function (issue 4217). + + Fix completion of try..finally (issue 2529). + + Extend Annex B 3.3 sloppy-mode block-scoped hoisting to scripts, eval + (issue 4441). + + [V8] Add name of function for function's closure scope (Chromium issue + 493156). + + Performance and stability improvements on all platforms. + + 2015-05-17: Sentinel The ChangeLog file is no longer maintained on bleeding_edge. This diff --git a/deps/v8/DEPS b/deps/v8/DEPS index 85d14c75fd3f5f..fc1ad8585ef936 100644 --- a/deps/v8/DEPS +++ b/deps/v8/DEPS @@ -8,25 +8,32 @@ vars = { deps = { "v8/build/gyp": - Var("git_url") + "/external/gyp.git" + "@" + "01528c7244837168a1c80f06ff60fa5a9793c824", + Var("git_url") + "/external/gyp.git" + "@" + "2c1e6cced23554ce84806e570acea637f6473afc", "v8/third_party/icu": - Var("git_url") + "/chromium/deps/icu.git" + "@" + "423fc7e1107fb08ccf007c4aeb76dcab8b2747c1", + Var("git_url") + "/chromium/deps/icu.git" + "@" + "42c58d4e49f2250039f0e98d43e0b76e8f5ca024", "v8/buildtools": - Var("git_url") + "/chromium/buildtools.git" + "@" + "e7111440c07a883b82ffbbe6d26c744dfc6c9673", + Var("git_url") + "/chromium/buildtools.git" + "@" + "4a95614772d9bcbd8bc197e1d9bd034e088fc740", "v8/tools/swarming_client": - Var('git_url') + '/external/swarming.client.git' + '@' + "6e5d2b21f0ac98396cd736097a985346feed1328", + Var('git_url') + '/external/swarming.client.git' + '@' + "8fce79620b04bbe5415ace1103db27505bdc4c06", "v8/testing/gtest": - Var("git_url") + "/external/googletest.git" + "@" + "9855a87157778d39b95eccfb201a9dc90f6d61c6", + Var("git_url") + "/external/github.com/google/googletest.git" + "@" + "6f8a66431cb592dad629028a50b3dd418a408c87", "v8/testing/gmock": Var("git_url") + "/external/googlemock.git" + "@" + "0421b6f358139f02e102c9c332ce19a33faf75be", + "v8/test/benchmarks/data": + Var("git_url") + "/v8/deps/third_party/benchmarks.git" + "@" + "05d7188267b4560491ff9155c5ee13e207ecd65f", + "v8/test/mozilla/data": + Var("git_url") + "/v8/deps/third_party/mozilla-tests.git" + "@" + "f6c578a10ea707b1a8ab0b88943fe5115ce2b9be", + "v8/test/simdjs/data": Var("git_url") + "/external/github.com/tc39/ecmascript_simd.git" + "@" + "c8ef63c728283debc25891123eb00482fee4b8cd", + "v8/test/test262/data": + Var("git_url") + "/external/github.com/tc39/test262.git" + "@" + "ea222fb7d09e334c321b987656315ad4056ded96", "v8/tools/clang": - Var("git_url") + "/chromium/src/tools/clang.git" + "@" + "0150e39a3112dbc7e4c7a3ab25276b8d7781f3b6", + Var("git_url") + "/chromium/src/tools/clang.git" + "@" + "66f5328417331216569e8beb244fd887f62e8997", } deps_os = { "android": { "v8/third_party/android_tools": - Var("git_url") + "/android_tools.git" + "@" + "4238a28593b7e6178c95431f91ca8c24e45fa7eb", + Var("git_url") + "/android_tools.git" + "@" + "54492f99c84cab0826a8e656efeb33a1b1bf5a04", }, "win": { "v8/third_party/cygwin": @@ -93,6 +100,46 @@ hooks = [ "-s", "v8/buildtools/linux64/clang-format.sha1", ], }, + # Pull luci-go binaries (isolate, swarming) using checked-in hashes. + { + 'name': 'luci-go_win', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=win32', + '--no_auth', + '--bucket', 'chromium-luci', + '-d', 'v8/tools/luci-go/win64', + ], + }, + { + 'name': 'luci-go_mac', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=darwin', + '--no_auth', + '--bucket', 'chromium-luci', + '-d', 'v8/tools/luci-go/mac64', + ], + }, + { + 'name': 'luci-go_linux', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=linux*', + '--no_auth', + '--bucket', 'chromium-luci', + '-d', 'v8/tools/luci-go/linux64', + ], + }, + { + # Update the Windows toolchain if necessary. + 'name': 'win_toolchain', + 'pattern': '.', + 'action': ['python', 'v8/build/vs_toolchain.py', 'update'], + }, # Pull binutils for linux, enabled debug fission for faster linking / # debugging when used with clang on Ubuntu Precise. # https://code.google.com/p/chromium/issues/detail?id=352046 diff --git a/deps/v8/README.md b/deps/v8/README.md index c649f02ec2c2f4..804df5edb47ed6 100644 --- a/deps/v8/README.md +++ b/deps/v8/README.md @@ -36,5 +36,5 @@ configuration in `.git/config`: Contributing ============= -Please follow the instructions mentioned on the +Please follow the instructions mentioned on the [V8 wiki](https://code.google.com/p/v8-wiki/wiki/Contributing). diff --git a/deps/v8/WATCHLISTS b/deps/v8/WATCHLISTS index f57dfa140258f3..a5699abcf1be65 100644 --- a/deps/v8/WATCHLISTS +++ b/deps/v8/WATCHLISTS @@ -42,6 +42,14 @@ 'debugger': { 'filepath': 'src/debug/', }, + 'interpreter': { + 'filepath': 'src/interpreter/', + 'filepath': 'test/cctest/interpreter/', + 'filepath': 'test/unittests/interpreter/', + }, + 'feature_shipping_status': { + 'filepath': 'src/flag-definitions.h', + }, }, 'WATCHLISTS': { @@ -54,5 +62,12 @@ 'debugger': [ 'yangguo@chromium.org', ], + 'interpreter': [ + 'rmcilroy@chromium.org', + 'oth@chromium.org', + ], + 'feature_shipping_status': [ + 'hablich@chromium.org', + ], }, } diff --git a/deps/v8/build/all.gyp b/deps/v8/build/all.gyp index 4aeb507dcab73e..0195083b0180ba 100644 --- a/deps/v8/build/all.gyp +++ b/deps/v8/build/all.gyp @@ -19,6 +19,22 @@ '../tools/parser-shell.gyp:parser-shell', ], }], + ['test_isolation_mode != "noop"', { + 'dependencies': [ + '../test/bot_default.gyp:*', + '../test/benchmarks/benchmarks.gyp:*', + '../test/default.gyp:*', + '../test/intl/intl.gyp:*', + '../test/message/message.gyp:*', + '../test/mjsunit/mjsunit.gyp:*', + '../test/mozilla/mozilla.gyp:*', + '../test/optimize_for_size.gyp:*', + '../test/preparser/preparser.gyp:*', + '../test/simdjs/simdjs.gyp:*', + '../test/test262/test262.gyp:*', + '../test/webkit/webkit.gyp:*', + ], + }], ] } ] diff --git a/deps/v8/build/config/win/msvs_dependencies.isolate b/deps/v8/build/config/win/msvs_dependencies.isolate new file mode 100644 index 00000000000000..ff922273634a9f --- /dev/null +++ b/deps/v8/build/config/win/msvs_dependencies.isolate @@ -0,0 +1,77 @@ +# Copyright 2015 the V8 project authors. All rights reserved. +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'conditions': [ + # Copy the VS runtime DLLs into the isolate so that they + # don't have to be preinstalled on the target machine. + # + # VS2013 runtimes + ['OS=="win" and msvs_version==2013 and component=="shared_library" and CONFIGURATION_NAME=="Debug"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/x64/msvcp120d.dll', + '<(PRODUCT_DIR)/x64/msvcr120d.dll', + ], + }, + }], + ['OS=="win" and msvs_version==2013 and component=="shared_library" and CONFIGURATION_NAME=="Release"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/x64/msvcp120.dll', + '<(PRODUCT_DIR)/x64/msvcr120.dll', + ], + }, + }], + ['OS=="win" and msvs_version==2013 and component=="shared_library" and (CONFIGURATION_NAME=="Debug" or CONFIGURATION_NAME=="Debug_x64")', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/msvcp120d.dll', + '<(PRODUCT_DIR)/msvcr120d.dll', + ], + }, + }], + ['OS=="win" and msvs_version==2013 and component=="shared_library" and (CONFIGURATION_NAME=="Release" or CONFIGURATION_NAME=="Release_x64")', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/msvcp120.dll', + '<(PRODUCT_DIR)/msvcr120.dll', + ], + }, + }], + # VS2015 runtimes + ['OS=="win" and msvs_version==2015 and component=="shared_library" and CONFIGURATION_NAME=="Debug"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/x64/msvcp140d.dll', + '<(PRODUCT_DIR)/x64/vccorlib140d.dll', + ], + }, + }], + ['OS=="win" and msvs_version==2015 and component=="shared_library" and CONFIGURATION_NAME=="Release"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/x64/msvcp140.dll', + '<(PRODUCT_DIR)/x64/vccorlib140.dll', + ], + }, + }], + ['OS=="win" and msvs_version==2015 and component=="shared_library" and (CONFIGURATION_NAME=="Debug" or CONFIGURATION_NAME=="Debug_x64")', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/msvcp140d.dll', + '<(PRODUCT_DIR)/vccorlib140d.dll', + ], + }, + }], + ['OS=="win" and msvs_version==2015 and component=="shared_library" and (CONFIGURATION_NAME=="Release" or CONFIGURATION_NAME=="Release_x64")', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/msvcp140.dll', + '<(PRODUCT_DIR)/vccorlib140.dll', + ], + }, + }], + ], +} \ No newline at end of file diff --git a/deps/v8/build/features.gypi b/deps/v8/build/features.gypi index 741ba75eb6dc87..03b3072c9b3bae 100644 --- a/deps/v8/build/features.gypi +++ b/deps/v8/build/features.gypi @@ -39,6 +39,8 @@ 'v8_trace_maps%': 0, + # Enable the snapshot feature, for fast context creation. + # http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html 'v8_use_snapshot%': 'true', 'v8_enable_verify_predictable%': 0, diff --git a/deps/v8/build/get_landmines.py b/deps/v8/build/get_landmines.py index 434b980c6db8b7..6e4dbb3468ec25 100755 --- a/deps/v8/build/get_landmines.py +++ b/deps/v8/build/get_landmines.py @@ -24,6 +24,7 @@ def main(): print 'Moar clobbering...' print 'Remove build/android.gypi' print 'Cleanup after windows ninja switch attempt.' + print 'Switching to pinned msvs toolchain.' return 0 diff --git a/deps/v8/build/gyp_environment.py b/deps/v8/build/gyp_environment.py index f1cee6ef8e00f6..7a4e6221482688 100644 --- a/deps/v8/build/gyp_environment.py +++ b/deps/v8/build/gyp_environment.py @@ -10,6 +10,7 @@ import os import sys +import vs_toolchain SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) V8_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir)) @@ -50,3 +51,4 @@ def set_environment(): # Update the environment based on v8.gyp_env gyp_env_path = os.path.join(os.path.dirname(V8_ROOT), 'v8.gyp_env') apply_gyp_environment(gyp_env_path) + vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs() diff --git a/deps/v8/build/gyp_v8 b/deps/v8/build/gyp_v8 index 8a8ffa1bdda388..8813f2c12162ba 100755 --- a/deps/v8/build/gyp_v8 +++ b/deps/v8/build/gyp_v8 @@ -30,6 +30,7 @@ # This script is wrapper for V8 that adds some support for how GYP # is invoked by V8 beyond what can be done in the gclient hooks. +import argparse import glob import gyp_environment import os @@ -37,6 +38,7 @@ import platform import shlex import subprocess import sys +import vs_toolchain script_dir = os.path.dirname(os.path.realpath(__file__)) v8_root = os.path.abspath(os.path.join(script_dir, os.pardir)) @@ -49,6 +51,25 @@ sys.path.insert( 1, os.path.abspath(os.path.join(v8_root, 'tools', 'generate_shim_headers'))) +def GetOutputDirectory(): + """Returns the output directory that GYP will use.""" + + # Handle command line generator flags. + parser = argparse.ArgumentParser() + parser.add_argument('-G', dest='genflags', default=[], action='append') + genflags = parser.parse_known_args()[0].genflags + + # Handle generator flags from the environment. + genflags += shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', '')) + + needle = 'output_dir=' + for item in genflags: + if item.startswith(needle): + return item[len(needle):] + + return 'out' + + def additional_include_files(args=[]): """ Returns a list of additional (.gypi) files to include, without @@ -82,6 +103,13 @@ def additional_include_files(args=[]): def run_gyp(args): rc = gyp.main(args) + vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs() + if vs2013_runtime_dll_dirs: + x64_runtime, x86_runtime = vs2013_runtime_dll_dirs + vs_toolchain.CopyVsRuntimeDlls( + os.path.join(v8_root, GetOutputDirectory()), + (x86_runtime, x64_runtime)) + if rc != 0: print 'Error running GYP' sys.exit(rc) @@ -130,6 +158,7 @@ if __name__ == '__main__': # Generate for the architectures supported on the given platform. gyp_args = list(args) + gyp_args.extend(['-D', 'gyp_output_dir=' + GetOutputDirectory()]) gyp_generators = os.environ.get('GYP_GENERATORS', '') if platform.system() == 'Linux' and gyp_generators != 'ninja': # Work around for crbug.com/331475. diff --git a/deps/v8/build/isolate.gypi b/deps/v8/build/isolate.gypi index 9e2a3bfee398de..5d30005e74a56b 100644 --- a/deps/v8/build/isolate.gypi +++ b/deps/v8/build/isolate.gypi @@ -44,6 +44,7 @@ 'extension': 'isolate', 'inputs': [ # Files that are known to be involved in this step. + '<(DEPTH)/tools/isolate_driver.py', '<(DEPTH)/tools/swarming_client/isolate.py', '<(DEPTH)/tools/swarming_client/run_isolated.py', ], @@ -52,7 +53,7 @@ ], 'action': [ 'python', - '<(DEPTH)/tools/swarming_client/isolate.py', + '<(DEPTH)/tools/isolate_driver.py', '<(test_isolation_mode)', '--isolated', '<(PRODUCT_DIR)/<(RULE_INPUT_ROOT).isolated', '--isolate', '<(RULE_INPUT_PATH)', @@ -66,8 +67,29 @@ '--path-variable', 'DEPTH', '<(DEPTH)', '--path-variable', 'PRODUCT_DIR', '<(PRODUCT_DIR)', + '--config-variable', 'CONFIGURATION_NAME=<(CONFIGURATION_NAME)', '--config-variable', 'OS=<(OS)', + '--config-variable', 'asan=<(asan)', + '--config-variable', 'cfi_vptr=<(cfi_vptr)', + '--config-variable', 'icu_use_data_file_flag=0', + '--config-variable', 'msan=<(msan)', + '--config-variable', 'tsan=<(tsan)', + '--config-variable', 'component=<(component)', + '--config-variable', 'target_arch=<(target_arch)', + '--config-variable', 'use_custom_libcxx=<(use_custom_libcxx)', '--config-variable', 'v8_use_external_startup_data=<(v8_use_external_startup_data)', + '--config-variable', 'v8_use_snapshot=<(v8_use_snapshot)', + ], + 'conditions': [ + ['OS=="win"', { + 'action': [ + '--config-variable', 'msvs_version=2013', + ], + }, { + 'action': [ + '--config-variable', 'msvs_version=0', + ], + }], ], }, ], diff --git a/deps/v8/build/standalone.gypi b/deps/v8/build/standalone.gypi index 7250579d27c123..fa4d45d4eb42f7 100644 --- a/deps/v8/build/standalone.gypi +++ b/deps/v8/build/standalone.gypi @@ -97,6 +97,10 @@ 'cfi_blacklist%': '<(base_dir)/tools/cfi/blacklist.txt', + # Set to 1 to enable fast builds. + # TODO(machenbach): Only configured for windows. + 'fastbuild%': 0, + # goma settings. # 1 to use goma. # If no gomadir is set, it uses the default gomadir. @@ -127,7 +131,7 @@ # TODO(machenbach): Remove the conditions as more configurations are # supported. - ['OS=="linux"', { + ['OS=="linux" or OS=="win"', { 'test_isolation_mode%': 'check', }, { 'test_isolation_mode%': 'noop', @@ -155,6 +159,7 @@ 'cfi_diag%': '<(cfi_diag)', 'cfi_blacklist%': '<(cfi_blacklist)', 'test_isolation_mode%': '<(test_isolation_mode)', + 'fastbuild%': '<(fastbuild)', # Add a simple extras solely for the purpose of the cctests 'v8_extra_library_files': ['../test/cctest/test-extra.js'], @@ -206,12 +211,8 @@ ['OS=="win" and use_goma==1', { # goma doesn't support pch yet. 'chromium_win_pch': 0, - # goma doesn't support PDB yet, so win_z7=1 or fastbuild=1. - 'conditions': [ - ['win_z7==0 and fastbuild==0', { - 'fastbuild': 1, - }], - ], + # goma doesn't support PDB yet. + 'fastbuild%': 1, }], ['((v8_target_arch=="ia32" or v8_target_arch=="x64" or v8_target_arch=="x87") and \ (OS=="linux" or OS=="mac")) or (v8_target_arch=="ppc64" and OS=="linux")', { @@ -433,6 +434,23 @@ }], ], }], + ['fastbuild!=0', { + 'conditions': [ + ['OS=="win" and fastbuild==1', { + 'msvs_settings': { + 'VCLinkerTool': { + # This tells the linker to generate .pdbs, so that + # we can get meaningful stack traces. + 'GenerateDebugInformation': 'true', + }, + 'VCCLCompilerTool': { + # No debug info to be generated by compiler. + 'DebugInformationFormat': '0', + }, + }, + }], + ], + }], # fastbuild!=0 ], 'target_conditions': [ ['v8_code == 0', { @@ -492,8 +510,8 @@ 'target_defaults': { 'conditions': [ # Common options for AddressSanitizer, LeakSanitizer, - # ThreadSanitizer and MemorySanitizer. - ['asan==1 or lsan==1 or tsan==1 or msan==1', { + # ThreadSanitizer, MemorySanitizer and CFI builds. + ['asan==1 or lsan==1 or tsan==1 or msan==1 or cfi_vptr==1', { 'target_conditions': [ ['_toolset=="target"', { 'cflags': [ @@ -1275,7 +1293,7 @@ ['_toolset=="target"', { 'cflags': [ '-fno-sanitize-trap=cfi', - '-fsanitize-recover=cfi', + '-fno-sanitize-recover=cfi', ], 'cflags_cc!': [ '-fno-rtti', @@ -1285,7 +1303,7 @@ ], 'ldflags': [ '-fno-sanitize-trap=cfi', - '-fsanitize-recover=cfi', + '-fno-sanitize-recover=cfi', ], }], ], diff --git a/deps/v8/build/toolchain.gypi b/deps/v8/build/toolchain.gypi index bd081e179107cc..7c96144b38520c 100644 --- a/deps/v8/build/toolchain.gypi +++ b/deps/v8/build/toolchain.gypi @@ -638,8 +638,8 @@ '_MIPS_ARCH_LOONGSON', 'FPU_MODE_FP32', ], - 'cflags!': ['-mfp64', '-mfp32', '-mfpxx'], - 'cflags': ['-mips3', '-Wa,-mips3'], + 'cflags!': ['-mfp64', '-mfpxx'], + 'cflags': ['-mips3', '-Wa,-mips3', '-mfp32'], }], ], }, { diff --git a/deps/v8/build/vs_toolchain.py b/deps/v8/build/vs_toolchain.py new file mode 100644 index 00000000000000..294ade38182a2b --- /dev/null +++ b/deps/v8/build/vs_toolchain.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python +# Copyright 2015 the V8 project authors. All rights reserved. +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import json +import os +import pipes +import shutil +import subprocess +import sys +import vs_toolchain + + +script_dir = os.path.dirname(os.path.realpath(__file__)) +chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir)) +SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(1, os.path.join(chrome_src, 'tools')) +sys.path.insert(0, os.path.join(chrome_src, 'build', 'gyp', 'pylib')) +json_data_file = os.path.join(script_dir, 'win_toolchain.json') + + +import gyp + + +def SetEnvironmentAndGetRuntimeDllDirs(): + """Sets up os.environ to use the depot_tools VS toolchain with gyp, and + returns the location of the VS runtime DLLs so they can be copied into + the output directory after gyp generation. + """ + vs2013_runtime_dll_dirs = None + depot_tools_win_toolchain = \ + bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))) + # When running on a non-Windows host, only do this if the SDK has explicitly + # been downloaded before (in which case json_data_file will exist). + if ((sys.platform in ('win32', 'cygwin') or os.path.exists(json_data_file)) + and depot_tools_win_toolchain): + if not os.path.exists(json_data_file): + Update() + with open(json_data_file, 'r') as tempf: + toolchain_data = json.load(tempf) + + toolchain = toolchain_data['path'] + version = toolchain_data['version'] + win_sdk = toolchain_data.get('win_sdk') + if not win_sdk: + win_sdk = toolchain_data['win8sdk'] + wdk = toolchain_data['wdk'] + # TODO(scottmg): The order unfortunately matters in these. They should be + # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call + # below). http://crbug.com/345992 + vs2013_runtime_dll_dirs = toolchain_data['runtime_dirs'] + + os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain + os.environ['GYP_MSVS_VERSION'] = version + # We need to make sure windows_sdk_path is set to the automated + # toolchain values in GYP_DEFINES, but don't want to override any + # otheroptions.express + # values there. + gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES')) + gyp_defines_dict['windows_sdk_path'] = win_sdk + os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v))) + for k, v in gyp_defines_dict.iteritems()) + os.environ['WINDOWSSDKDIR'] = win_sdk + os.environ['WDK_DIR'] = wdk + # Include the VS runtime in the PATH in case it's not machine-installed. + runtime_path = ';'.join(vs2013_runtime_dll_dirs) + os.environ['PATH'] = runtime_path + ';' + os.environ['PATH'] + return vs2013_runtime_dll_dirs + + +def _VersionNumber(): + """Gets the standard version number ('120', '140', etc.) based on + GYP_MSVS_VERSION.""" + if os.environ['GYP_MSVS_VERSION'] == '2013': + return '120' + elif os.environ['GYP_MSVS_VERSION'] == '2015': + return '140' + else: + raise ValueError('Unexpected GYP_MSVS_VERSION') + + +def _CopyRuntimeImpl(target, source): + """Copy |source| to |target| if it doesn't already exist or if it + needs to be updated. + """ + if (os.path.isdir(os.path.dirname(target)) and + (not os.path.isfile(target) or + os.stat(target).st_mtime != os.stat(source).st_mtime)): + print 'Copying %s to %s...' % (source, target) + if os.path.exists(target): + os.unlink(target) + shutil.copy2(source, target) + + +def _CopyRuntime2013(target_dir, source_dir, dll_pattern): + """Copy both the msvcr and msvcp runtime DLLs, only if the target doesn't + exist, but the target directory does exist.""" + for file_part in ('p', 'r'): + dll = dll_pattern % file_part + target = os.path.join(target_dir, dll) + source = os.path.join(source_dir, dll) + _CopyRuntimeImpl(target, source) + + +def _CopyRuntime2015(target_dir, source_dir, dll_pattern): + """Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't + exist, but the target directory does exist.""" + for file_part in ('msvcp', 'vccorlib'): + dll = dll_pattern % file_part + target = os.path.join(target_dir, dll) + source = os.path.join(source_dir, dll) + _CopyRuntimeImpl(target, source) + + +def CopyVsRuntimeDlls(output_dir, runtime_dirs): + """Copies the VS runtime DLLs from the given |runtime_dirs| to the output + directory so that even if not system-installed, built binaries are likely to + be able to run. + + This needs to be run after gyp has been run so that the expected target + output directories are already created. + """ + x86, x64 = runtime_dirs + out_debug = os.path.join(output_dir, 'Debug') + out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64') + out_release = os.path.join(output_dir, 'Release') + out_release_nacl64 = os.path.join(output_dir, 'Release', 'x64') + out_debug_x64 = os.path.join(output_dir, 'Debug_x64') + out_release_x64 = os.path.join(output_dir, 'Release_x64') + + if os.path.exists(out_debug) and not os.path.exists(out_debug_nacl64): + os.makedirs(out_debug_nacl64) + if os.path.exists(out_release) and not os.path.exists(out_release_nacl64): + os.makedirs(out_release_nacl64) + if os.environ.get('GYP_MSVS_VERSION') == '2015': + _CopyRuntime2015(out_debug, x86, '%s140d.dll') + _CopyRuntime2015(out_release, x86, '%s140.dll') + _CopyRuntime2015(out_debug_x64, x64, '%s140d.dll') + _CopyRuntime2015(out_release_x64, x64, '%s140.dll') + _CopyRuntime2015(out_debug_nacl64, x64, '%s140d.dll') + _CopyRuntime2015(out_release_nacl64, x64, '%s140.dll') + else: + # VS2013 is the default. + _CopyRuntime2013(out_debug, x86, 'msvc%s120d.dll') + _CopyRuntime2013(out_release, x86, 'msvc%s120.dll') + _CopyRuntime2013(out_debug_x64, x64, 'msvc%s120d.dll') + _CopyRuntime2013(out_release_x64, x64, 'msvc%s120.dll') + _CopyRuntime2013(out_debug_nacl64, x64, 'msvc%s120d.dll') + _CopyRuntime2013(out_release_nacl64, x64, 'msvc%s120.dll') + + # Copy the PGO runtime library to the release directories. + if os.environ.get('GYP_MSVS_OVERRIDE_PATH'): + pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'), + 'VC', 'bin') + pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64') + pgo_runtime_dll = 'pgort' + _VersionNumber() + '.dll' + source_x86 = os.path.join(pgo_x86_runtime_dir, pgo_runtime_dll) + if os.path.exists(source_x86): + _CopyRuntimeImpl(os.path.join(out_release, pgo_runtime_dll), source_x86) + source_x64 = os.path.join(pgo_x64_runtime_dir, pgo_runtime_dll) + if os.path.exists(source_x64): + _CopyRuntimeImpl(os.path.join(out_release_x64, pgo_runtime_dll), + source_x64) + + +def CopyDlls(target_dir, configuration, target_cpu): + """Copy the VS runtime DLLs into the requested directory as needed. + + configuration is one of 'Debug' or 'Release'. + target_cpu is one of 'x86' or 'x64'. + + The debug configuration gets both the debug and release DLLs; the + release config only the latter. + """ + vs2013_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs() + if not vs2013_runtime_dll_dirs: + return + + x64_runtime, x86_runtime = vs2013_runtime_dll_dirs + runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime + _CopyRuntime2013( + target_dir, runtime_dir, 'msvc%s' + _VersionNumber() + '.dll') + if configuration == 'Debug': + _CopyRuntime2013( + target_dir, runtime_dir, 'msvc%s' + _VersionNumber() + 'd.dll') + + +def _GetDesiredVsToolchainHashes(): + """Load a list of SHA1s corresponding to the toolchains that we want installed + to build with.""" + if os.environ.get('GYP_MSVS_VERSION') == '2015': + return ['49ae4b60d898182fc3f521c2fcda82c453915011'] + else: + # Default to VS2013. + return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef'] + + +def Update(force=False): + """Requests an update of the toolchain to the specific hashes we have at + this revision. The update outputs a .json of the various configuration + information required to pass to gyp which we use in |GetToolchainDir()|. + """ + if force != False and force != '--force': + print >>sys.stderr, 'Unknown parameter "%s"' % force + return 1 + if force == '--force' or os.path.exists(json_data_file): + force = True + + depot_tools_win_toolchain = \ + bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))) + if ((sys.platform in ('win32', 'cygwin') or force) and + depot_tools_win_toolchain): + import find_depot_tools + depot_tools_path = find_depot_tools.add_depot_tools_to_path() + get_toolchain_args = [ + sys.executable, + os.path.join(depot_tools_path, + 'win_toolchain', + 'get_toolchain_if_necessary.py'), + '--output-json', json_data_file, + ] + _GetDesiredVsToolchainHashes() + if force: + get_toolchain_args.append('--force') + subprocess.check_call(get_toolchain_args) + + return 0 + + +def GetToolchainDir(): + """Gets location information about the current toolchain (must have been + previously updated by 'update'). This is used for the GN build.""" + runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs() + + # If WINDOWSSDKDIR is not set, search the default SDK path and set it. + if not 'WINDOWSSDKDIR' in os.environ: + default_sdk_path = 'C:\\Program Files (x86)\\Windows Kits\\8.1' + if os.path.isdir(default_sdk_path): + os.environ['WINDOWSSDKDIR'] = default_sdk_path + + print '''vs_path = "%s" +sdk_path = "%s" +vs_version = "%s" +wdk_dir = "%s" +runtime_dirs = "%s" +''' % ( + os.environ['GYP_MSVS_OVERRIDE_PATH'], + os.environ['WINDOWSSDKDIR'], + os.environ['GYP_MSVS_VERSION'], + os.environ.get('WDK_DIR', ''), + ';'.join(runtime_dll_dirs or ['None'])) + + +def main(): + commands = { + 'update': Update, + 'get_toolchain_dir': GetToolchainDir, + 'copy_dlls': CopyDlls, + } + if len(sys.argv) < 2 or sys.argv[1] not in commands: + print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands) + return 1 + return commands[sys.argv[1]](*sys.argv[2:]) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/deps/v8/docs/arm_debugging_with_the_simulator.md b/deps/v8/docs/arm_debugging_with_the_simulator.md index eceb7a58abb79c..fbb415614237f5 100644 --- a/deps/v8/docs/arm_debugging_with_the_simulator.md +++ b/deps/v8/docs/arm_debugging_with_the_simulator.md @@ -64,23 +64,23 @@ test(); ``` $ out/arm.debug/d8 func.js --stop_at test -Simulator hit stop-at - 0xb544d6a8 e92d4902 stmdb sp!, {r1, r8, fp, lr} -sim> print r0 -r0: 0xb547ec15 -1253577707 -sim> printobject r0 -r0: -0xb547ec15: [Function] - - map = 0x0xb540ff01 - - initial_map = - - shared_info = 0xb547eb2d - - name = #test - - context = 0xb60083f1 - - code = 0xb544d681 - #arguments: 0xb545a15d (callback) - #length: 0xb545a14d (callback) - #name: 0xb545a155 (callback) - #prototype: 0xb545a145 (callback) +Simulator hit stop-at + 0xb544d6a8 e92d4902 stmdb sp!, {r1, r8, fp, lr} +sim> print r0 +r0: 0xb547ec15 -1253577707 +sim> printobject r0 +r0: +0xb547ec15: [Function] + - map = 0x0xb540ff01 + - initial_map = + - shared_info = 0xb547eb2d + - name = #test + - context = 0xb60083f1 + - code = 0xb544d681 + #arguments: 0xb545a15d (callback) + #length: 0xb545a14d (callback) + #name: 0xb545a155 (callback) + #prototype: 0xb545a145 (callback) #caller: 0xb545a165 (callback) ``` @@ -92,31 +92,31 @@ You can have only one such breakpoint. This is useful if you want to insert a br ``` $ out/arm.debug/d8 func.js --stop_at test -Simulator hit stop-at - 0xb53a1ee8 e92d4902 stmdb sp!, {r1, r8, fp, lr} -sim> disasm 5 - 0xb53a1ee8 e92d4902 stmdb sp!, {r1, r8, fp, lr} - 0xb53a1eec e28db008 add fp, sp, #8 - 0xb53a1ef0 e59a200c ldr r2, [r10, #+12] - 0xb53a1ef4 e28fe004 add lr, pc, #4 - 0xb53a1ef8 e15d0002 cmp sp, r2 -sim> break 0xb53a1ef8 -sim> cont - 0xb53a1ef8 e15d0002 cmp sp, r2 -sim> disasm 5 - 0xb53a1ef8 e15d0002 cmp sp, r2 - 0xb53a1efc 359ff034 ldrcc pc, [pc, #+52] - 0xb53a1f00 e5980017 ldr r0, [r8, #+23] - 0xb53a1f04 e59f1030 ldr r1, [pc, #+48] - 0xb53a1f08 e52d0004 str r0, [sp, #-4]! -sim> break 0xb53a1f08 -setting breakpoint failed -sim> del -sim> break 0xb53a1f08 -sim> cont - 0xb53a1f08 e52d0004 str r0, [sp, #-4]! -sim> del -sim> cont +Simulator hit stop-at + 0xb53a1ee8 e92d4902 stmdb sp!, {r1, r8, fp, lr} +sim> disasm 5 + 0xb53a1ee8 e92d4902 stmdb sp!, {r1, r8, fp, lr} + 0xb53a1eec e28db008 add fp, sp, #8 + 0xb53a1ef0 e59a200c ldr r2, [r10, #+12] + 0xb53a1ef4 e28fe004 add lr, pc, #4 + 0xb53a1ef8 e15d0002 cmp sp, r2 +sim> break 0xb53a1ef8 +sim> cont + 0xb53a1ef8 e15d0002 cmp sp, r2 +sim> disasm 5 + 0xb53a1ef8 e15d0002 cmp sp, r2 + 0xb53a1efc 359ff034 ldrcc pc, [pc, #+52] + 0xb53a1f00 e5980017 ldr r0, [r8, #+23] + 0xb53a1f04 e59f1030 ldr r1, [pc, #+48] + 0xb53a1f08 e52d0004 str r0, [sp, #-4]! +sim> break 0xb53a1f08 +setting breakpoint failed +sim> del +sim> break 0xb53a1f08 +sim> cont + 0xb53a1f08 e52d0004 str r0, [sp, #-4]! +sim> del +sim> cont In function test. ``` @@ -127,18 +127,18 @@ The first argument is a help message, the second is the condition, and the third If we are working on this v8 C++ code, which is reached when running our JavaScript file. ``` -__ stop("My stop.", al, 123); +__ stop("My stop.", al, 123); +__ mov(r0, r0); +__ mov(r0, r0); __ mov(r0, r0); __ mov(r0, r0); -__ mov(r0, r0); -__ mov(r0, r0); -__ mov(r0, r0); -__ stop("My second stop.", al, 0x1); -__ mov(r1, r1); -__ mov(r1, r1); -__ mov(r1, r1); -__ mov(r1, r1); +__ mov(r0, r0); +__ stop("My second stop.", al, 0x1); +__ mov(r1, r1); +__ mov(r1, r1); +__ mov(r1, r1); __ mov(r1, r1); +__ mov(r1, r1); ``` Here's a sample debugging session: @@ -146,60 +146,60 @@ Here's a sample debugging session: We hit the first stop. ``` -Simulator hit My stop. +Simulator hit My stop. 0xb53559e8 e1a00000 mov r0, r0 ``` We can see the following stop using disasm. The address of the message string is inlined in the code after the svc stop instruction. ``` -sim> disasm - 0xb53559e8 e1a00000 mov r0, r0 - 0xb53559ec e1a00000 mov r0, r0 - 0xb53559f0 e1a00000 mov r0, r0 - 0xb53559f4 e1a00000 mov r0, r0 - 0xb53559f8 e1a00000 mov r0, r0 - 0xb53559fc ef800001 stop 1 - 0x1 - 0xb5355a00 08338a97 stop message: My second stop - 0xb5355a04 e1a00000 mov r1, r1 - 0xb5355a08 e1a00000 mov r1, r1 +sim> disasm + 0xb53559e8 e1a00000 mov r0, r0 + 0xb53559ec e1a00000 mov r0, r0 + 0xb53559f0 e1a00000 mov r0, r0 + 0xb53559f4 e1a00000 mov r0, r0 + 0xb53559f8 e1a00000 mov r0, r0 + 0xb53559fc ef800001 stop 1 - 0x1 + 0xb5355a00 08338a97 stop message: My second stop + 0xb5355a04 e1a00000 mov r1, r1 + 0xb5355a08 e1a00000 mov r1, r1 0xb5355a0c e1a00000 mov r1, r1 ``` Information can be printed for all (watched) stops which were hit at least once. ``` -sim> stop info all -Stop information: -stop 123 - 0x7b: Enabled, counter = 1, My stop. -sim> cont -Simulator hit My second stop - 0xb5355a04 e1a00000 mov r1, r1 -sim> stop info all -Stop information: -stop 1 - 0x1: Enabled, counter = 1, My second stop +sim> stop info all +Stop information: +stop 123 - 0x7b: Enabled, counter = 1, My stop. +sim> cont +Simulator hit My second stop + 0xb5355a04 e1a00000 mov r1, r1 +sim> stop info all +Stop information: +stop 1 - 0x1: Enabled, counter = 1, My second stop stop 123 - 0x7b: Enabled, counter = 1, My stop. ``` Stops can be disabled or enabled. (Only available for watched stops.) ``` -sim> stop disable 1 -sim> cont -Simulator hit My stop. - 0xb5356808 e1a00000 mov r0, r0 -sim> cont -Simulator hit My stop. - 0xb5356c28 e1a00000 mov r0, r0 -sim> stop info all -Stop information: -stop 1 - 0x1: Disabled, counter = 2, My second stop -stop 123 - 0x7b: Enabled, counter = 3, My stop. -sim> stop enable 1 -sim> cont -Simulator hit My second stop - 0xb5356c44 e1a00000 mov r1, r1 -sim> stop disable all +sim> stop disable 1 +sim> cont +Simulator hit My stop. + 0xb5356808 e1a00000 mov r0, r0 +sim> cont +Simulator hit My stop. + 0xb5356c28 e1a00000 mov r0, r0 +sim> stop info all +Stop information: +stop 1 - 0x1: Disabled, counter = 2, My second stop +stop 123 - 0x7b: Enabled, counter = 3, My stop. +sim> stop enable 1 +sim> cont +Simulator hit My second stop + 0xb5356c44 e1a00000 mov r1, r1 +sim> stop disable all sim> con In function test. ``` \ No newline at end of file diff --git a/deps/v8/docs/becoming_v8_committer.md b/deps/v8/docs/becoming_v8_committer.md index 16e8491b06f1f9..0a927b3ca9f72d 100644 --- a/deps/v8/docs/becoming_v8_committer.md +++ b/deps/v8/docs/becoming_v8_committer.md @@ -1,6 +1,8 @@ +# Becoming a V8 committer + ## What is a committer? -Technically, a committer is someone who has write access to the V8 SVN repository. A committer can submit his or her own patches or patches from others. +Technically, a committer is someone who has write access to the V8 Git repository. A committer can submit his or her own patches or patches from others. This privilege is granted with some expectation of responsibility: committers are people who care about the V8 project and want to help meet its goals. A committer is not just someone who can make changes, but someone who has demonstrated his or her ability to collaborate with the team, get the most knowledgeable people to review code, contribute high-quality code, and follow through to fix issues (in code or tests). @@ -35,4 +37,4 @@ You don't really need to do much to maintain committer status: just keep being a In the unhappy event that a committer continues to disregard good citizenship (or actively disrupts the project), we may need to revoke that person's status. The process is the same as for nominating a new committer: someone suggests the revocation with a good reason, two people second the motion, and a vote may be called if consensus cannot be reached. I hope that's simple enough, and that we never have to test it in practice. -(Source: inspired by http://dev.chromium.org/getting-involved/become-a-committer ) \ No newline at end of file +(Source: inspired by http://dev.chromium.org/getting-involved/become-a-committer ) diff --git a/deps/v8/docs/cross_compiling_for_arm.md b/deps/v8/docs/cross_compiling_for_arm.md index 68464eff1f5568..30a7196b4a9c7c 100644 --- a/deps/v8/docs/cross_compiling_for_arm.md +++ b/deps/v8/docs/cross_compiling_for_arm.md @@ -118,7 +118,7 @@ export ARM_TARGET_LIB=/opt/codesourcery/arm-2010.09-103/arm-none-linux-gnueabi/l cd target -scons -Y$V8DIR wordsize=32 snapshot=nobuild arch=armsample=shell +scons -Y$V8DIR wordsize=32 snapshot=nobuild arch=armsample=shell rm $V8DIR/src/snapshot.cc cd .. diff --git a/deps/v8/docs/debugger_protocol.md b/deps/v8/docs/debugger_protocol.md index 6b6b448a0f8cde..2cc618fbd4cbfb 100644 --- a/deps/v8/docs/debugger_protocol.md +++ b/deps/v8/docs/debugger_protocol.md @@ -100,7 +100,7 @@ The request `evaluate` is used to evaluate an expression. The body of the result "additional_context" : [ { "name" : , "handle" : }, { "name" : , "handle" : }, - ... + ... ] } } diff --git a/deps/v8/docs/gdb_jit_interface.md b/deps/v8/docs/gdb_jit_interface.md index 753626cf6f1444..7fcea824eeaace 100644 --- a/deps/v8/docs/gdb_jit_interface.md +++ b/deps/v8/docs/gdb_jit_interface.md @@ -18,7 +18,7 @@ When GDB JIT interface is disabled a typical backtrace in GDB will contain frame #11 0xf5cc38f4 in ?? () #12 0xf5cbef19 in ?? () #13 0xf5cb09a2 in ?? () -#14 0x0809e0a5 in v8::internal::Invoke (construct=false, func=..., receiver=..., argc=0, args=0x0, +#14 0x0809e0a5 in v8::internal::Invoke (construct=false, func=..., receiver=..., argc=0, args=0x0, has_pending_exception=0xffffd46f) at src/execution.cc:97 ``` @@ -31,7 +31,7 @@ However enabling GDB JIT integration allows GDB to produce more informative stac #9 0xf5cc38f4 in test.js () at test.js:13 #10 0xf5cbef19 in ?? () #11 0xf5cb09a2 in ?? () -#12 0x0809e1f9 in v8::internal::Invoke (construct=false, func=..., receiver=..., argc=0, args=0x0, +#12 0x0809e1f9 in v8::internal::Invoke (construct=false, func=..., receiver=..., argc=0, args=0x0, has_pending_exception=0xffffd44f) at src/execution.cc:97 ``` diff --git a/deps/v8/docs/merging_and_patching.md b/deps/v8/docs/merging_and_patching.md index d141f329840c7f..b173b475c33d3c 100644 --- a/deps/v8/docs/merging_and_patching.md +++ b/deps/v8/docs/merging_and_patching.md @@ -4,7 +4,8 @@ If you have a patch to the master branch (e.g. an important bug fix) that needs For the examples, a branched 2.4 version of V8 will be used. Substitute "2.4" with your version number. -**An associated issue is mandatory if a patch is merged. This helps with keeping track of merges.** +**An associated issue on Chromium's or V8's issue tracker is mandatory if a patch is merged. This helps with keeping track of merges. +You can use [a template](https://code.google.com/p/v8/issues/entry?template=Merge%20request) to create an issue.** # Merge process outlined @@ -60,7 +61,7 @@ Version 2.4.9.10: Issue xxx: The parser doesn't parse. ## I get an error during merge that is related to tagging. What should I do? When two people are merging at the same time a race-condition can happen in the merge scripts. If this is the case, contact machenbach@chromium.org and hablich@chromium.org. ## Is there a TL;DR;? - 1. Create issue + 1. [Create issue on issue tracker](https://code.google.com/p/v8/issues/entry?template=Merge%20request) 1. Add Merge-Request-{Branch} to the issue 1. Wait until somebody will add Merge-Approved-{Branch} - 1. Merge \ No newline at end of file + 1. Merge diff --git a/deps/v8/docs/runtime_functions.md b/deps/v8/docs/runtime_functions.md index 4f99fdb2ca8f3d..3ebd587868a249 100644 --- a/deps/v8/docs/runtime_functions.md +++ b/deps/v8/docs/runtime_functions.md @@ -1,14 +1,7 @@ -# Introduction +# Runtime functions Much of the JavaScript library is implemented in JavaScript code itself, using a minimal set of C++ runtime functions callable from JavaScript. Some of these are called using names that start with %, and using the flag "--allow-natives-syntax". Others are only called by code generated by the code generators, and are not visible in JS, even using the % syntax. - - class CustomArguments; class PropertyCallbackArguments; class FunctionCallbackArguments; class GlobalHandles; -} +} // namespace internal /** @@ -311,6 +312,7 @@ class Local { friend class String; friend class Object; friend class Context; + friend class Private; template friend class internal::CustomArguments; friend Local Undefined(Isolate* isolate); friend Local Null(Isolate* isolate); @@ -603,6 +605,13 @@ template class PersistentBase { */ V8_INLINE void MarkPartiallyDependent(); + /** + * Marks the reference to this object as active. The scavenge garbage + * collection should not reclaim the objects marked as active. + * This bit is cleared after the each garbage collection pass. + */ + V8_INLINE void MarkActive(); + V8_INLINE bool IsIndependent() const; /** Checks if the handle holds the only reference to an object. */ @@ -966,8 +975,8 @@ class V8_EXPORT SealHandleScope { void operator delete(void*, size_t); internal::Isolate* isolate_; - int prev_level_; internal::Object** prev_limit_; + int prev_sealed_level_; }; @@ -2465,6 +2474,7 @@ class V8_EXPORT Symbol : public Name { static Local GetIterator(Isolate* isolate); static Local GetUnscopables(Isolate* isolate); static Local GetToStringTag(Isolate* isolate); + static Local GetIsConcatSpreadable(Isolate* isolate); V8_INLINE static Symbol* Cast(v8::Value* obj); @@ -2474,6 +2484,34 @@ class V8_EXPORT Symbol : public Name { }; +/** + * A private symbol + * + * This is an experimental feature. Use at your own risk. + */ +class V8_EXPORT Private : public Data { + public: + // Returns the print name string of the private symbol, or undefined if none. + Local Name() const; + + // Create a private symbol. If name is not empty, it will be the description. + static Local New(Isolate* isolate, + Local name = Local()); + + // Retrieve a global private symbol. If a symbol with this name has not + // been retrieved in the same isolate before, it is created. + // Note that private symbols created this way are never collected, so + // they should only be used for statically fixed properties. + // Also, there is only one global name space for the names used as keys. + // To minimize the potential for clashes, use qualified names as keys, + // e.g., "Class#property". + static Local ForApi(Isolate* isolate, Local name); + + private: + Private(); +}; + + /** * A JavaScript number value (ECMA-262, 4.3.20) */ @@ -2701,6 +2739,18 @@ class V8_EXPORT Object : public Value { PropertyAttribute attribute = None, AccessControl settings = DEFAULT); + /** + * Functionality for private properties. + * This is an experimental feature, use at your own risk. + * Note: Private properties are not inherited. Do not rely on this, since it + * may change. + */ + Maybe HasPrivate(Local context, Local key); + Maybe SetPrivate(Local context, Local key, + Local value); + Maybe DeletePrivate(Local context, Local key); + MaybeLocal GetPrivate(Local context, Local key); + /** * Returns an array containing the names of the enumerable properties * of this object, including properties from prototype objects. The @@ -2869,16 +2919,12 @@ class V8_EXPORT Object : public Value { */ int GetIdentityHash(); - /** - * Access hidden properties on JavaScript objects. These properties are - * hidden from the executing JavaScript and only accessible through the V8 - * C++ API. Hidden properties introduced by V8 internally (for example the - * identity hash) are prefixed with "v8::". - */ - // TODO(dcarney): convert these to take a isolate and optionally bailout? - bool SetHiddenValue(Local key, Local value); - Local GetHiddenValue(Local key); - bool DeleteHiddenValue(Local key); + V8_DEPRECATE_SOON("Use v8::Object::SetPrivate instead.", + bool SetHiddenValue(Local key, Local value)); + V8_DEPRECATE_SOON("Use v8::Object::GetHidden instead.", + Local GetHiddenValue(Local key)); + V8_DEPRECATE_SOON("Use v8::Object::DeletePrivate instead.", + bool DeleteHiddenValue(Local key)); /** * Clone this object with a fast but shallow copy. Values will point @@ -3955,7 +4001,9 @@ class V8_EXPORT RegExp : public Object { kNone = 0, kGlobal = 1, kIgnoreCase = 2, - kMultiline = 4 + kMultiline = 4, + kSticky = 8, + kUnicode = 16 }; /** @@ -4007,6 +4055,15 @@ class V8_EXPORT External : public Value { }; +#define V8_INTRINSICS_LIST(F) F(ArrayProto_values, array_values_iterator) + +enum Intrinsic { +#define V8_DECL_INTRINSIC(name, iname) k##name, + V8_INTRINSICS_LIST(V8_DECL_INTRINSIC) +#undef V8_DECL_INTRINSIC +}; + + // --- Templates --- @@ -4027,13 +4084,6 @@ class V8_EXPORT Template : public Data { PropertyAttribute attribute = None, AccessControl settings = DEFAULT); -#ifdef V8_JS_ACCESSORS - void SetAccessorProperty(Local name, - Local getter = Local(), - Local setter = Local(), - PropertyAttribute attribute = None); -#endif // V8_JS_ACCESSORS - /** * Whenever the property with the given name is accessed on objects * created from this Template the getter and setter callbacks @@ -4076,6 +4126,13 @@ class V8_EXPORT Template : public Data { Local signature = Local(), AccessControl settings = DEFAULT); + /** + * During template instantiation, sets the value with the intrinsic property + * from the correct context. + */ + void SetIntrinsicDataProperty(Local name, Intrinsic intrinsic, + PropertyAttribute attribute = None); + private: Template(); @@ -4234,6 +4291,14 @@ enum AccessType { }; +/** + * Returns true if the given context should be allowed to access the given + * object. + */ +typedef bool (*AccessCheckCallback)(Local accessing_context, + Local accessed_object); + + /** * Returns true if cross-context access should be allowed to the named * property with the given key on the host object. @@ -4642,16 +4707,21 @@ class V8_EXPORT ObjectTemplate : public Template { void MarkAsUndetectable(); /** - * Sets access check callbacks on the object template and enables - * access checks. + * Sets access check callback on the object template and enables access + * checks. * * When accessing properties on instances of this object template, * the access check callback will be called to determine whether or * not to allow cross-context access to the properties. */ - void SetAccessCheckCallbacks(NamedSecurityCallback named_handler, - IndexedSecurityCallback indexed_handler, - Local data = Local()); + void SetAccessCheckCallback(AccessCheckCallback callback, + Local data = Local()); + + V8_DEPRECATE_SOON( + "Use SetAccessCheckCallback instead", + void SetAccessCheckCallbacks(NamedSecurityCallback named_handler, + IndexedSecurityCallback indexed_handler, + Local data = Local())); /** * Gets the number of internal fields for objects generated from @@ -5006,6 +5076,7 @@ class V8_EXPORT HeapStatistics { size_t total_available_size() { return total_available_size_; } size_t used_heap_size() { return used_heap_size_; } size_t heap_size_limit() { return heap_size_limit_; } + size_t does_zap_garbage() { return does_zap_garbage_; } private: size_t total_heap_size_; @@ -5014,6 +5085,7 @@ class V8_EXPORT HeapStatistics { size_t total_available_size_; size_t used_heap_size_; size_t heap_size_limit_; + bool does_zap_garbage_; friend class V8; friend class Isolate; @@ -5351,6 +5423,9 @@ class V8_EXPORT Isolate { kSlotsBufferOverflow = 5, kObjectObserve = 6, kForcedGC = 7, + kSloppyMode = 8, + kStrictMode = 9, + kStrongMode = 10, kUseCounterFeatureCount // This enum value must be last. }; @@ -5521,7 +5596,10 @@ class V8_EXPORT Isolate { /** Returns true if this isolate has a current context. */ bool InContext(); - /** Returns the context that is on the top of the stack. */ + /** + * Returns the context of the currently running JavaScript, or the context + * on the top of the stack if no JavaScript is running. + */ Local GetCurrentContext(); /** @@ -5529,9 +5607,12 @@ class V8_EXPORT Isolate { * context of the top-most JavaScript frame. If there are no * JavaScript frames an empty handle is returned. */ - Local GetCallingContext(); + V8_DEPRECATE_SOON( + "Calling context concept is not compatible with tail calls, and will be " + "removed.", + Local GetCallingContext()); - /** Returns the last entered context. */ + /** Returns the last context entered through V8's C++ API. */ Local GetEnteredContext(); /** @@ -5789,6 +5870,18 @@ class V8_EXPORT Isolate { */ int ContextDisposedNotification(bool dependant_context = true); + /** + * Optional notification that the isolate switched to the foreground. + * V8 uses these notifications to guide heuristics. + */ + void IsolateInForegroundNotification(); + + /** + * Optional notification that the isolate switched to the background. + * V8 uses these notifications to guide heuristics. + */ + void IsolateInBackgroundNotification(); + /** * Allows the host application to provide the address of a function that is * notified each time code is added, moved or removed. @@ -5918,6 +6011,13 @@ class V8_EXPORT Isolate { */ void VisitHandlesForPartialDependence(PersistentHandleVisitor* visitor); + /** + * Iterates through all the persistent handles in the current isolate's heap + * that have class_ids and are weak to be marked as inactive if there is no + * pending activity for the handle. + */ + void VisitWeakHandles(PersistentHandleVisitor* visitor); + private: template friend class PersistentValueMapBase; @@ -7000,6 +7100,7 @@ class Internals { static const int kNodeStateIsNearDeathValue = 4; static const int kNodeIsIndependentShift = 3; static const int kNodeIsPartiallyDependentShift = 4; + static const int kNodeIsActiveShift = 4; static const int kJSObjectType = 0xb7; static const int kFirstNonstringType = 0x80; @@ -7326,6 +7427,15 @@ void PersistentBase::MarkPartiallyDependent() { } +template +void PersistentBase::MarkActive() { + typedef internal::Internals I; + if (this->IsEmpty()) return; + I::UpdateNodeFlag(reinterpret_cast(this->val_), true, + I::kNodeIsActiveShift); +} + + template void PersistentBase::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h index 4f4b2cd55eae9b..c88e1da15e9125 100644 --- a/deps/v8/include/v8config.h +++ b/deps/v8/include/v8config.h @@ -174,6 +174,7 @@ // supported // V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported // V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported +// V8_HAS_ATTRIBUTE_NORETURN - __attribute__((noreturn)) supported // V8_HAS_ATTRIBUTE_UNUSED - __attribute__((unused)) supported // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported // V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result)) @@ -190,6 +191,7 @@ // V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported +// V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported // V8_HAS___FORCEINLINE - __forceinline supported // // Note that testing for compilers and/or features must be done using #if @@ -212,6 +214,7 @@ # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) # define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated)) # define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline)) +# define V8_HAS_ATTRIBUTE_NORETURN (__has_attribute(noreturn)) # define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused)) # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility)) # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ @@ -253,6 +256,7 @@ # define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE (V8_GNUC_PREREQ(4, 5, 0)) # define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0)) +# define V8_HAS_ATTRIBUTE_NORETURN (V8_GNUC_PREREQ(2, 5, 0)) # define V8_HAS_ATTRIBUTE_UNUSED (V8_GNUC_PREREQ(2, 95, 0)) # define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0)) # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ @@ -285,6 +289,7 @@ # define V8_HAS_DECLSPEC_DEPRECATED 1 # define V8_HAS_DECLSPEC_NOINLINE 1 # define V8_HAS_DECLSPEC_SELECTANY 1 +# define V8_HAS_DECLSPEC_NORETURN 1 # define V8_HAS___FORCEINLINE 1 @@ -319,6 +324,18 @@ #endif +// A macro used to tell the compiler that a particular function never returns. +// Use like: +// V8_NORETURN void MyAbort() { abort(); } +#if V8_HAS_ATTRIBUTE_NORETURN +# define V8_NORETURN __attribute__((noreturn)) +#elif HAS_DECLSPEC_NORETURN +# define V8_NORETURN __declspec(noreturn) +#else +# define V8_NORETURN /* NOT SUPPORTED */ +#endif + + // A macro (V8_DEPRECATED) to mark classes or functions as deprecated. #if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE #define V8_DEPRECATED(message, declarator) \ diff --git a/deps/v8/samples/shell.cc b/deps/v8/samples/shell.cc index ad2228508439f6..b89ffdd180e9b2 100644 --- a/deps/v8/samples/shell.cc +++ b/deps/v8/samples/shell.cc @@ -412,9 +412,11 @@ void ReportException(v8::Isolate* isolate, v8::TryCatch* try_catch) { fprintf(stderr, "^"); } fprintf(stderr, "\n"); - v8::String::Utf8Value stack_trace( - try_catch->StackTrace(context).ToLocalChecked()); - if (stack_trace.length() > 0) { + v8::Local stack_trace_string; + if (try_catch->StackTrace(context).ToLocal(&stack_trace_string) && + stack_trace_string->IsString() && + v8::Local::Cast(stack_trace_string)->Length() > 0) { + v8::String::Utf8Value stack_trace(stack_trace_string); const char* stack_trace_string = ToCString(stack_trace); fprintf(stderr, "%s\n", stack_trace_string); } diff --git a/deps/v8/snapshot_toolchain.gni b/deps/v8/snapshot_toolchain.gni index f41a5ee0e83590..c419c3ff06c5ab 100644 --- a/deps/v8/snapshot_toolchain.gni +++ b/deps/v8/snapshot_toolchain.gni @@ -42,3 +42,5 @@ if (host_cpu == "x64" && host_os == "linux") { } else { snapshot_toolchain = default_toolchain } + + diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc index b89917f73ecd7c..73270d187c5ed4 100644 --- a/deps/v8/src/accessors.cc +++ b/deps/v8/src/accessors.cc @@ -198,18 +198,6 @@ void Accessors::ArrayLengthGetter( } -// Tries to non-observably convert |value| to a valid array length. -// Returns false if it fails. -static bool FastAsArrayLength(Isolate* isolate, Handle value, - uint32_t* length) { - if (value->ToArrayLength(length)) return true; - // We don't support AsArrayLength, so use AsArrayIndex for now. This just - // misses out on kMaxUInt32. - if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); - return false; -} - - void Accessors::ArrayLengthSetter( v8::Local name, v8::Local val, @@ -222,26 +210,9 @@ void Accessors::ArrayLengthSetter( Handle length_obj = Utils::OpenHandle(*val); uint32_t length = 0; - if (!FastAsArrayLength(isolate, length_obj, &length)) { - Handle uint32_v; - if (!Object::ToUint32(isolate, length_obj).ToHandle(&uint32_v)) { - isolate->OptionalRescheduleException(false); - return; - } - - Handle number_v; - if (!Object::ToNumber(length_obj).ToHandle(&number_v)) { - isolate->OptionalRescheduleException(false); - return; - } - - if (uint32_v->Number() != number_v->Number()) { - Handle exception = isolate->factory()->NewRangeError( - MessageTemplate::kInvalidArrayLength); - return isolate->ScheduleThrow(*exception); - } - - CHECK(uint32_v->ToArrayLength(&length)); + if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { + isolate->OptionalRescheduleException(false); + return; } if (JSArray::ObservableSetLength(array, length).is_null()) { @@ -260,7 +231,6 @@ Handle Accessors::ArrayLengthInfo( } - // // Accessors::StringLength // @@ -1074,7 +1044,12 @@ void Accessors::FunctionNameGetter( HandleScope scope(isolate); Handle function = Handle::cast(Utils::OpenHandle(*info.Holder())); - Handle result(function->shared()->name(), isolate); + Handle result; + if (function->shared()->name_should_print_as_anonymous()) { + result = isolate->factory()->anonymous_string(); + } else { + result = handle(function->shared()->name(), isolate); + } info.GetReturnValue().Set(Utils::ToLocal(result)); } @@ -1200,20 +1175,7 @@ Handle GetFunctionArguments(Isolate* isolate, return ArgumentsForInlinedFunction(frame, function, function_index); } - if (!frame->is_optimized()) { - // If there is an arguments variable in the stack, we return that. - Handle scope_info(function->shared()->scope_info()); - int index = scope_info->StackSlotIndex( - isolate->heap()->arguments_string()); - if (index >= 0) { - Handle arguments(frame->GetExpression(index), isolate); - if (!arguments->IsArgumentsMarker()) return arguments; - } - } - - // If there is no arguments variable in the stack or we have an - // optimized frame, we find the frame that holds the actual arguments - // passed to the function. + // Find the frame that holds the actual arguments passed to the function. it.AdvanceToArgumentsFrame(); frame = it.frame(); @@ -1359,7 +1321,7 @@ MaybeHandle FindCaller(Isolate* isolate, // If caller is a built-in function and caller's caller is also built-in, // use that instead. JSFunction* potential_caller = caller; - while (potential_caller != NULL && potential_caller->IsBuiltin()) { + while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) { caller = potential_caller; potential_caller = it.next(); } diff --git a/deps/v8/src/accessors.h b/deps/v8/src/accessors.h index 3c0079de89dcc5..6c1765c404ddcd 100644 --- a/deps/v8/src/accessors.h +++ b/deps/v8/src/accessors.h @@ -106,6 +106,7 @@ class Accessors : public AllStatic { Handle accessor); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ACCESSORS_H_ diff --git a/deps/v8/src/address-map.cc b/deps/v8/src/address-map.cc new file mode 100644 index 00000000000000..681661af2978bb --- /dev/null +++ b/deps/v8/src/address-map.cc @@ -0,0 +1,38 @@ +// 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. + +#include "src/address-map.h" +#include "src/heap/heap.h" +#include "src/isolate.h" +#include "src/objects-inl.h" + +namespace v8 { +namespace internal { + +RootIndexMap::RootIndexMap(Isolate* isolate) { + map_ = isolate->root_index_map(); + if (map_ != NULL) return; + map_ = new HashMap(HashMap::PointersMatch); + for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) { + Heap::RootListIndex root_index = static_cast(i); + Object* root = isolate->heap()->root(root_index); + // Omit root entries that can be written after initialization. They must + // not be referenced through the root list in the snapshot. + if (root->IsHeapObject() && + isolate->heap()->RootCanBeTreatedAsConstant(root_index)) { + HeapObject* heap_object = HeapObject::cast(root); + HashMap::Entry* entry = LookupEntry(map_, heap_object, false); + if (entry != NULL) { + // Some are initialized to a previous value in the root list. + DCHECK_LT(GetValue(entry), i); + } else { + SetValue(LookupEntry(map_, heap_object, true), i); + } + } + } + isolate->set_root_index_map(map_); +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/address-map.h b/deps/v8/src/address-map.h new file mode 100644 index 00000000000000..df32f89c1ea33c --- /dev/null +++ b/deps/v8/src/address-map.h @@ -0,0 +1,184 @@ +// 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. + +#ifndef V8_ADDRESS_MAP_H_ +#define V8_ADDRESS_MAP_H_ + +#include "src/assert-scope.h" +#include "src/hashmap.h" +#include "src/objects.h" + +namespace v8 { +namespace internal { + +class AddressMapBase { + protected: + static void SetValue(HashMap::Entry* entry, uint32_t v) { + entry->value = reinterpret_cast(v); + } + + static uint32_t GetValue(HashMap::Entry* entry) { + return static_cast(reinterpret_cast(entry->value)); + } + + inline static HashMap::Entry* LookupEntry(HashMap* map, HeapObject* obj, + bool insert) { + if (insert) { + map->LookupOrInsert(Key(obj), Hash(obj)); + } + return map->Lookup(Key(obj), Hash(obj)); + } + + private: + static uint32_t Hash(HeapObject* obj) { + return static_cast(reinterpret_cast(obj->address())); + } + + static void* Key(HeapObject* obj) { + return reinterpret_cast(obj->address()); + } +}; + + +class RootIndexMap : public AddressMapBase { + public: + explicit RootIndexMap(Isolate* isolate); + + static const int kInvalidRootIndex = -1; + + int Lookup(HeapObject* obj) { + HashMap::Entry* entry = LookupEntry(map_, obj, false); + if (entry) return GetValue(entry); + return kInvalidRootIndex; + } + + private: + HashMap* map_; + + DISALLOW_COPY_AND_ASSIGN(RootIndexMap); +}; + + +class BackReference { + public: + explicit BackReference(uint32_t bitfield) : bitfield_(bitfield) {} + + BackReference() : bitfield_(kInvalidValue) {} + + static BackReference SourceReference() { return BackReference(kSourceValue); } + + static BackReference GlobalProxyReference() { + return BackReference(kGlobalProxyValue); + } + + static BackReference LargeObjectReference(uint32_t index) { + return BackReference(SpaceBits::encode(LO_SPACE) | + ChunkOffsetBits::encode(index)); + } + + static BackReference DummyReference() { return BackReference(kDummyValue); } + + static BackReference Reference(AllocationSpace space, uint32_t chunk_index, + uint32_t chunk_offset) { + DCHECK(IsAligned(chunk_offset, kObjectAlignment)); + DCHECK_NE(LO_SPACE, space); + return BackReference( + SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | + ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); + } + + bool is_valid() const { return bitfield_ != kInvalidValue; } + bool is_source() const { return bitfield_ == kSourceValue; } + bool is_global_proxy() const { return bitfield_ == kGlobalProxyValue; } + + AllocationSpace space() const { + DCHECK(is_valid()); + return SpaceBits::decode(bitfield_); + } + + uint32_t chunk_offset() const { + DCHECK(is_valid()); + return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; + } + + uint32_t large_object_index() const { + DCHECK(is_valid()); + DCHECK(chunk_index() == 0); + return ChunkOffsetBits::decode(bitfield_); + } + + uint32_t chunk_index() const { + DCHECK(is_valid()); + return ChunkIndexBits::decode(bitfield_); + } + + uint32_t reference() const { + DCHECK(is_valid()); + return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); + } + + uint32_t bitfield() const { return bitfield_; } + + private: + static const uint32_t kInvalidValue = 0xFFFFFFFF; + static const uint32_t kSourceValue = 0xFFFFFFFE; + static const uint32_t kGlobalProxyValue = 0xFFFFFFFD; + static const uint32_t kDummyValue = 0xFFFFFFFC; + static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; + static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; + + public: + static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1; + + private: + class ChunkOffsetBits : public BitField {}; + class ChunkIndexBits + : public BitField {}; + class SpaceBits + : public BitField { + }; + + uint32_t bitfield_; +}; + + +// Mapping objects to their location after deserialization. +// This is used during building, but not at runtime by V8. +class BackReferenceMap : public AddressMapBase { + public: + BackReferenceMap() + : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {} + + ~BackReferenceMap() { delete map_; } + + BackReference Lookup(HeapObject* obj) { + HashMap::Entry* entry = LookupEntry(map_, obj, false); + return entry ? BackReference(GetValue(entry)) : BackReference(); + } + + void Add(HeapObject* obj, BackReference b) { + DCHECK(b.is_valid()); + DCHECK_NULL(LookupEntry(map_, obj, false)); + HashMap::Entry* entry = LookupEntry(map_, obj, true); + SetValue(entry, b.bitfield()); + } + + void AddSourceString(String* string) { + Add(string, BackReference::SourceReference()); + } + + void AddGlobalProxy(HeapObject* global_proxy) { + Add(global_proxy, BackReference::GlobalProxyReference()); + } + + private: + DisallowHeapAllocation no_allocation_; + HashMap* map_; + DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_ADDRESS_MAP_H_ diff --git a/deps/v8/src/allocation-site-scopes.h b/deps/v8/src/allocation-site-scopes.h index 9e287c131075d8..96e74c5ddbbfa8 100644 --- a/deps/v8/src/allocation-site-scopes.h +++ b/deps/v8/src/allocation-site-scopes.h @@ -36,7 +36,7 @@ class AllocationSiteContext { void InitializeTraversal(Handle site) { top_ = site; - current_ = Handle(*top_, isolate()); + current_ = Handle::New(*top_, isolate()); } private: @@ -95,6 +95,7 @@ class AllocationSiteUsageContext : public AllocationSiteContext { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ALLOCATION_SITE_SCOPES_H_ diff --git a/deps/v8/src/allocation.h b/deps/v8/src/allocation.h index 292e1fe23b5f8a..7c1e023b8646f8 100644 --- a/deps/v8/src/allocation.h +++ b/deps/v8/src/allocation.h @@ -88,6 +88,7 @@ class FreeStoreAllocationPolicy { void* AlignedAlloc(size_t size, size_t alignment); void AlignedFree(void *ptr); -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ALLOCATION_H_ diff --git a/deps/v8/src/api-natives.cc b/deps/v8/src/api-natives.cc index 051ea4a17b15c1..d8dd1510417641 100644 --- a/deps/v8/src/api-natives.cc +++ b/deps/v8/src/api-natives.cc @@ -37,25 +37,6 @@ MaybeHandle Instantiate(Isolate* isolate, Handle data, } -MaybeHandle InstantiateFunctionOrMaybeDont(Isolate* isolate, - Handle data) { - DCHECK(data->IsFunctionTemplateInfo() || data->IsJSFunction()); - if (data->IsFunctionTemplateInfo()) { - // A function template needs to be instantiated. - return InstantiateFunction(isolate, - Handle::cast(data)); -#ifdef V8_JS_ACCESSORS - } else if (data->IsJSFunction()) { - // If we already have a proper function, we do not need additional work. - // (This should only happen for JavaScript API accessors.) - return Handle::cast(data); -#endif // V8_JS_ACCESSORS - } else { - UNREACHABLE(); - return MaybeHandle(); - } -} - MaybeHandle DefineAccessorProperty(Isolate* isolate, Handle object, Handle name, @@ -63,14 +44,18 @@ MaybeHandle DefineAccessorProperty(Isolate* isolate, Handle setter, PropertyAttributes attributes) { if (!getter->IsUndefined()) { - ASSIGN_RETURN_ON_EXCEPTION(isolate, getter, - InstantiateFunctionOrMaybeDont(isolate, getter), - Object); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, getter, + InstantiateFunction(isolate, + Handle::cast(getter)), + Object); } if (!setter->IsUndefined()) { - ASSIGN_RETURN_ON_EXCEPTION(isolate, setter, - InstantiateFunctionOrMaybeDont(isolate, setter), - Object); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, setter, + InstantiateFunction(isolate, + Handle::cast(setter)), + Object); } RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter, setter, attributes), @@ -102,8 +87,10 @@ MaybeHandle DefineDataProperty(Isolate* isolate, } #endif - return Object::AddDataProperty(&it, value, attributes, STRICT, - Object::CERTAINLY_NOT_STORE_FROM_KEYED); + MAYBE_RETURN_NULL( + Object::AddDataProperty(&it, value, attributes, Object::THROW_ON_ERROR, + Object::CERTAINLY_NOT_STORE_FROM_KEYED)); + return value; } @@ -148,6 +135,20 @@ class AccessCheckDisableScope { }; +Object* GetIntrinsic(Isolate* isolate, v8::Intrinsic intrinsic) { + Handle native_context = isolate->native_context(); + DCHECK(!native_context.is_null()); + switch (intrinsic) { +#define GET_INTRINSIC_VALUE(name, iname) \ + case v8::k##name: \ + return native_context->iname(); + V8_INTRINSICS_LIST(GET_INTRINSIC_VALUE) +#undef GET_INTRINSIC_VALUE + } + return nullptr; +} + + MaybeHandle ConfigureInstance(Isolate* isolate, Handle obj, Handle data) { auto property_list = handle(data->property_list(), isolate); @@ -162,23 +163,40 @@ MaybeHandle ConfigureInstance(Isolate* isolate, Handle obj, int i = 0; for (int c = 0; c < data->number_of_properties(); c++) { auto name = handle(Name::cast(properties.get(i++)), isolate); - PropertyDetails details(Smi::cast(properties.get(i++))); - PropertyAttributes attributes = details.attributes(); - PropertyKind kind = details.kind(); + auto bit = handle(properties.get(i++), isolate); + if (bit->IsSmi()) { + PropertyDetails details(Smi::cast(*bit)); + PropertyAttributes attributes = details.attributes(); + PropertyKind kind = details.kind(); + + if (kind == kData) { + auto prop_data = handle(properties.get(i++), isolate); + + RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, + prop_data, attributes), + JSObject); + } else { + auto getter = handle(properties.get(i++), isolate); + auto setter = handle(properties.get(i++), isolate); + RETURN_ON_EXCEPTION(isolate, + DefineAccessorProperty(isolate, obj, name, getter, + setter, attributes), + JSObject); + } + } else { + // Intrinsic data property --- Get appropriate value from the current + // context. + PropertyDetails details(Smi::cast(properties.get(i++))); + PropertyAttributes attributes = details.attributes(); + DCHECK_EQ(kData, details.kind()); - if (kind == kData) { - auto prop_data = handle(properties.get(i++), isolate); + v8::Intrinsic intrinsic = + static_cast(Smi::cast(properties.get(i++))->value()); + auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, prop_data, attributes), JSObject); - } else { - auto getter = handle(properties.get(i++), isolate); - auto setter = handle(properties.get(i++), isolate); - RETURN_ON_EXCEPTION(isolate, - DefineAccessorProperty(isolate, obj, name, getter, - setter, attributes), - JSObject); } } return obj; @@ -268,9 +286,9 @@ MaybeHandle InstantiateFunction(Isolate* isolate, JSObject::GetProperty(parent_instance, isolate->factory()->prototype_string()), JSFunction); - RETURN_ON_EXCEPTION( - isolate, JSObject::SetPrototype(prototype, parent_prototype, false), - JSFunction); + MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false, + Object::THROW_ON_ERROR), + MaybeHandle()); } } auto function = ApiNatives::CreateApiFunction( @@ -377,21 +395,25 @@ void ApiNatives::AddDataProperty(Isolate* isolate, Handle info, } +void ApiNatives::AddDataProperty(Isolate* isolate, Handle info, + Handle name, v8::Intrinsic intrinsic, + PropertyAttributes attributes) { + const int kSize = 4; + auto value = handle(Smi::FromInt(intrinsic), isolate); + auto intrinsic_marker = isolate->factory()->true_value(); + PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); + auto details_handle = handle(details.AsSmi(), isolate); + Handle data[kSize] = {name, intrinsic_marker, details_handle, value}; + AddPropertyToPropertyList(isolate, info, kSize, data); +} + + void ApiNatives::AddAccessorProperty(Isolate* isolate, Handle info, - Handle name, Handle getter, - Handle setter, + Handle name, + Handle getter, + Handle setter, PropertyAttributes attributes) { -#ifdef V8_JS_ACCESSORS - DCHECK(getter.is_null() || getter->IsFunctionTemplateInfo() || - getter->IsJSFunction()); - DCHECK(setter.is_null() || setter->IsFunctionTemplateInfo() || - setter->IsJSFunction()); -#else - DCHECK(getter.is_null() || getter->IsFunctionTemplateInfo()); - DCHECK(setter.is_null() || setter->IsFunctionTemplateInfo()); -#endif // V8_JS_ACCESSORS - const int kSize = 4; PropertyDetails details(attributes, ACCESSOR, 0, PropertyCellType::kNoCell); auto details_handle = handle(details.AsSmi(), isolate); diff --git a/deps/v8/src/api-natives.h b/deps/v8/src/api-natives.h index 0639677b155fda..fcca4a5a17e638 100644 --- a/deps/v8/src/api-natives.h +++ b/deps/v8/src/api-natives.h @@ -44,9 +44,14 @@ class ApiNatives { Handle name, Handle value, PropertyAttributes attributes); + static void AddDataProperty(Isolate* isolate, Handle info, + Handle name, v8::Intrinsic intrinsic, + PropertyAttributes attributes); + static void AddAccessorProperty(Isolate* isolate, Handle info, - Handle name, Handle getter, - Handle setter, + Handle name, + Handle getter, + Handle setter, PropertyAttributes attributes); static void AddNativeDataProperty(Isolate* isolate, Handle info, diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index fd9477e101557c..5d4c9c0c415ac5 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -43,6 +43,7 @@ #include "src/profiler/profile-generator-inl.h" #include "src/profiler/sampler.h" #include "src/property.h" +#include "src/property-descriptor.h" #include "src/property-details.h" #include "src/prototype.h" #include "src/runtime/runtime.h" @@ -158,6 +159,7 @@ class CallDepthScope { do_callback_(do_callback) { // TODO(dcarney): remove this when blink stops crashing. DCHECK(!isolate_->external_caught_exception()); + isolate_->IncrementJsCallsFromApiCounter(); isolate_->handle_scope_implementer()->IncrementCallDepth(); if (!context_.IsEmpty()) context_->Enter(); } @@ -734,17 +736,17 @@ SealHandleScope::SealHandleScope(Isolate* isolate) { i::HandleScopeData* current = internal_isolate->handle_scope_data(); prev_limit_ = current->limit; current->limit = current->next; - prev_level_ = current->level; - current->level = 0; + prev_sealed_level_ = current->sealed_level; + current->sealed_level = current->level; } SealHandleScope::~SealHandleScope() { i::HandleScopeData* current = isolate_->handle_scope_data(); - DCHECK_EQ(0, current->level); - current->level = prev_level_; DCHECK_EQ(current->next, current->limit); current->limit = prev_limit_; + DCHECK_EQ(current->level, current->sealed_level); + current->sealed_level = prev_sealed_level_; } @@ -955,25 +957,6 @@ void Template::SetAccessorProperty( } -#ifdef V8_JS_ACCESSORS -void Template::SetAccessorProperty(v8::Local name, - v8::Local getter, - v8::Local setter, - v8::PropertyAttribute attribute) { - auto templ = Utils::OpenHandle(this); - auto isolate = templ->GetIsolate(); - ENTER_V8(isolate); - DCHECK(!name.IsEmpty()); - DCHECK(!getter.IsEmpty() || !setter.IsEmpty()); - i::HandleScope scope(isolate); - i::ApiNatives::AddAccessorProperty( - isolate, templ, Utils::OpenHandle(*name), - Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true), - static_cast(attribute)); -} -#endif // V8_JS_ACCESSORS - - // --- F u n c t i o n T e m p l a t e --- static void InitializeFunctionTemplate( i::Handle info) { @@ -1352,6 +1335,18 @@ void Template::SetNativeDataProperty(v8::Local name, } +void Template::SetIntrinsicDataProperty(Local name, Intrinsic intrinsic, + PropertyAttribute attribute) { + auto templ = Utils::OpenHandle(this); + i::Isolate* isolate = templ->GetIsolate(); + ENTER_V8(isolate); + i::HandleScope scope(isolate); + i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name), + intrinsic, + static_cast(attribute)); +} + + void ObjectTemplate::SetAccessor(v8::Local name, AccessorGetterCallback getter, AccessorSetterCallback setter, @@ -1440,6 +1435,33 @@ void ObjectTemplate::MarkAsUndetectable() { } +void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback, + Local data) { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + ENTER_V8(isolate); + i::HandleScope scope(isolate); + auto cons = EnsureConstructor(isolate, this); + EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback"); + + i::Handle struct_info = + isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE); + i::Handle info = + i::Handle::cast(struct_info); + + SET_FIELD_WRAPPED(info, set_callback, callback); + SET_FIELD_WRAPPED(info, set_named_callback, nullptr); + SET_FIELD_WRAPPED(info, set_indexed_callback, nullptr); + + if (data.IsEmpty()) { + data = v8::Undefined(reinterpret_cast(isolate)); + } + info->set_data(*Utils::OpenHandle(*data)); + + cons->set_access_check_info(*info); + cons->set_needs_access_check(true); +} + + void ObjectTemplate::SetAccessCheckCallbacks( NamedSecurityCallback named_callback, IndexedSecurityCallback indexed_callback, Local data) { @@ -1454,6 +1476,7 @@ void ObjectTemplate::SetAccessCheckCallbacks( i::Handle info = i::Handle::cast(struct_info); + SET_FIELD_WRAPPED(info, set_callback, nullptr); SET_FIELD_WRAPPED(info, set_named_callback, named_callback); SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback); @@ -1968,7 +1991,8 @@ MaybeLocal ScriptCompiler::CompileFunctionInContext( Utils::OpenHandle(*v8_context->Global()), 0, nullptr).ToHandle(&result); RETURN_ON_FAILED_EXECUTION(Function); - RETURN_ESCAPED(Utils::ToLocal(i::Handle::cast(result))); + RETURN_ESCAPED( + Utils::CallableToLocal(i::Handle::cast(result))); } @@ -2686,9 +2710,7 @@ bool Value::IsFalse() const { } -bool Value::IsFunction() const { - return Utils::OpenHandle(this)->IsJSFunction(); -} +bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); } bool Value::IsName() const { @@ -3027,8 +3049,7 @@ void v8::Object::CheckCast(Value* that) { void v8::Function::CheckCast(Value* that) { i::Handle obj = Utils::OpenHandle(that); - Utils::ApiCheck(obj->IsJSFunction(), - "v8::Function::Cast()", + Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast()", "Could not convert to function"); } @@ -3494,30 +3515,26 @@ Maybe v8::Object::DefineOwnProperty(v8::Local context, v8::PropertyAttribute attributes) { PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DefineOwnProperty()", bool); - auto self = Utils::OpenHandle(this); - auto key_obj = Utils::OpenHandle(*key); - auto value_obj = Utils::OpenHandle(*value); + i::Handle self = Utils::OpenHandle(this); + i::Handle key_obj = Utils::OpenHandle(*key); + i::Handle value_obj = Utils::OpenHandle(*value); - if (self->IsAccessCheckNeeded() && !isolate->MayAccess(self)) { + if (self->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), self)) { isolate->ReportFailedAccessCheck(self); return Nothing(); } - i::Handle desc = isolate->factory()->NewFixedArray(3); - desc->set(0, isolate->heap()->ToBoolean(!(attributes & v8::ReadOnly))); - desc->set(1, isolate->heap()->ToBoolean(!(attributes & v8::DontEnum))); - desc->set(2, isolate->heap()->ToBoolean(!(attributes & v8::DontDelete))); - i::Handle desc_array = - isolate->factory()->NewJSArrayWithElements(desc, i::FAST_ELEMENTS, 3); - i::Handle args[] = {self, key_obj, value_obj, desc_array}; - i::Handle undefined = isolate->factory()->undefined_value(); - i::Handle fun = isolate->object_define_own_property(); - i::Handle result; - has_pending_exception = - !i::Execution::Call(isolate, fun, undefined, arraysize(args), args) - .ToHandle(&result); + i::PropertyDescriptor desc; + desc.set_writable(!(attributes & v8::ReadOnly)); + desc.set_enumerable(!(attributes & v8::DontEnum)); + desc.set_configurable(!(attributes & v8::DontDelete)); + desc.set_value(value_obj); + bool success = i::JSReceiver::DefineOwnProperty(isolate, self, key_obj, &desc, + i::Object::DONT_THROW); + // Even though we said DONT_THROW, there might be accessors that do throw. RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); - return Just(result->BooleanValue()); + return Just(success); } @@ -3526,20 +3543,12 @@ static i::MaybeHandle DefineObjectProperty( i::Handle js_object, i::Handle key, i::Handle value, PropertyAttributes attrs) { i::Isolate* isolate = js_object->GetIsolate(); - // Check if the given key is an array index. - uint32_t index = 0; - if (key->ToArrayIndex(&index)) { - return i::JSObject::SetOwnElementIgnoreAttributes(js_object, index, value, - attrs); - } - - i::Handle name; - ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name, - i::Object::ToName(isolate, key), - i::MaybeHandle()); + bool success = false; + i::LookupIterator it = i::LookupIterator::PropertyOrElement( + isolate, js_object, key, &success, i::LookupIterator::OWN); + if (!success) return i::MaybeHandle(); - return i::JSObject::DefinePropertyOrElementIgnoreAttributes(js_object, name, - value, attrs); + return i::JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs); } @@ -3575,6 +3584,13 @@ bool v8::Object::ForceSet(v8::Local key, v8::Local value, } +Maybe v8::Object::SetPrivate(Local context, Local key, + Local value) { + return DefineOwnProperty(context, Local(reinterpret_cast(*key)), + value, DontEnum); +} + + MaybeLocal v8::Object::Get(Local context, Local key) { PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value); @@ -3611,6 +3627,12 @@ Local v8::Object::Get(uint32_t index) { } +MaybeLocal v8::Object::GetPrivate(Local context, + Local key) { + return Get(context, Local(reinterpret_cast(*key))); +} + + Maybe v8::Object::GetPropertyAttributes( Local context, Local key) { PREPARE_FOR_EXECUTION_PRIMITIVE( @@ -3680,8 +3702,9 @@ Maybe v8::Object::SetPrototype(Local context, // We do not allow exceptions thrown while setting the prototype // to propagate outside. TryCatch try_catch(reinterpret_cast(isolate)); - auto result = i::JSObject::SetPrototype(self, value_obj, false); - has_pending_exception = result.is_null(); + auto result = i::JSObject::SetPrototype(self, value_obj, false, + i::Object::THROW_ON_ERROR); + has_pending_exception = result.IsNothing(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return Just(true); } @@ -3705,6 +3728,7 @@ Local v8::Object::FindInstanceInPrototypeChain( return Local(); } } + // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here. return Utils::ToLocal(i::handle(iter.GetCurrent(), isolate)); } @@ -3846,6 +3870,12 @@ bool v8::Object::Delete(v8::Local key) { } +Maybe v8::Object::DeletePrivate(Local context, + Local key) { + return Delete(context, Local(reinterpret_cast(*key))); +} + + Maybe v8::Object::Has(Local context, Local key) { PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool); auto self = Utils::OpenHandle(this); @@ -3874,6 +3904,11 @@ bool v8::Object::Has(v8::Local key) { } +Maybe v8::Object::HasPrivate(Local context, Local key) { + return HasOwnProperty(context, Local(reinterpret_cast(*key))); +} + + Maybe v8::Object::Delete(Local context, uint32_t index) { PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()", bool); @@ -4072,13 +4107,14 @@ MaybeLocal v8::Object::GetRealNamedPropertyInPrototypeChain( Local context, Local key) { PREPARE_FOR_EXECUTION( context, "v8::Object::GetRealNamedPropertyInPrototypeChain()", Value); - auto self = Utils::OpenHandle(this); - auto key_obj = Utils::OpenHandle(*key); + i::Handle self = Utils::OpenHandle(this); + i::Handle key_obj = Utils::OpenHandle(*key); i::PrototypeIterator iter(isolate, self); if (iter.IsAtEnd()) return MaybeLocal(); - auto proto = i::PrototypeIterator::GetCurrent(iter); + i::Handle proto = + i::PrototypeIterator::GetCurrent(iter); i::LookupIterator it = i::LookupIterator::PropertyOrElement( - isolate, self, key_obj, i::Handle::cast(proto), + isolate, self, key_obj, proto, i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); Local result; has_pending_exception = !ToLocal(i::Object::GetProperty(&it), &result); @@ -4102,22 +4138,20 @@ v8::Object::GetRealNamedPropertyAttributesInPrototypeChain( PREPARE_FOR_EXECUTION_PRIMITIVE( context, "v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()", PropertyAttribute); - auto self = Utils::OpenHandle(this); - auto key_obj = Utils::OpenHandle(*key); + i::Handle self = Utils::OpenHandle(this); + i::Handle key_obj = Utils::OpenHandle(*key); i::PrototypeIterator iter(isolate, self); if (iter.IsAtEnd()) return Nothing(); - auto proto = i::PrototypeIterator::GetCurrent(iter); + i::Handle proto = + i::PrototypeIterator::GetCurrent(iter); i::LookupIterator it = i::LookupIterator::PropertyOrElement( - isolate, self, key_obj, i::Handle::cast(proto), + isolate, self, key_obj, proto, i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); - auto result = i::JSReceiver::GetPropertyAttributes(&it); + Maybe result = i::JSReceiver::GetPropertyAttributes(&it); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); if (!it.IsFound()) return Nothing(); - if (result.FromJust() == ABSENT) { - return Just(static_cast(NONE)); - } - return Just( - static_cast(result.FromJust())); + if (result.FromJust() == ABSENT) return Just(None); + return Just(static_cast(result.FromJust())); } @@ -4206,13 +4240,16 @@ int v8::Object::GetIdentityHash() { bool v8::Object::SetHiddenValue(v8::Local key, v8::Local value) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); - if (value.IsEmpty()) return DeleteHiddenValue(key); ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle self = Utils::OpenHandle(this); i::Handle key_obj = Utils::OpenHandle(*key); i::Handle key_string = isolate->factory()->InternalizeString(key_obj); + if (value.IsEmpty()) { + i::JSObject::DeleteHiddenProperty(self, key_string); + return true; + } i::Handle value_obj = Utils::OpenHandle(*value); i::Handle result = i::JSObject::SetHiddenProperty(self, key_string, value_obj); @@ -4336,8 +4373,8 @@ MaybeLocal Function::NewInstance(Local context, int argc, STATIC_ASSERT(sizeof(v8::Local) == sizeof(i::Object**)); i::Handle* args = reinterpret_cast*>(argv); Local result; - has_pending_exception = - !ToLocal(i::Execution::New(self, argc, args), &result); + has_pending_exception = !ToLocal( + i::Execution::New(isolate, self, self, argc, args), &result); RETURN_ON_FAILED_EXECUTION(Object); RETURN_ESCAPED(result); } @@ -4375,20 +4412,32 @@ Local Function::Call(v8::Local recv, int argc, void Function::SetName(v8::Local name) { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) return; + auto func = i::Handle::cast(self); func->shared()->set_name(*Utils::OpenHandle(*name)); } Local Function::GetName() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return ToApiHandle( + self->GetIsolate()->factory()->undefined_value()); + } + auto func = i::Handle::cast(self); return Utils::ToLocal(i::Handle(func->shared()->name(), func->GetIsolate())); } Local Function::GetInferredName() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return ToApiHandle( + self->GetIsolate()->factory()->undefined_value()); + } + auto func = i::Handle::cast(self); return Utils::ToLocal(i::Handle(func->shared()->inferred_name(), func->GetIsolate())); } @@ -4397,7 +4446,11 @@ Local Function::GetInferredName() const { Local Function::GetDisplayName() const { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return ToApiHandle(isolate->factory()->undefined_value()); + } + auto func = i::Handle::cast(self); i::Handle property_name = isolate->factory()->NewStringFromStaticChars("displayName"); i::Handle value = @@ -4411,7 +4464,11 @@ Local Function::GetDisplayName() const { ScriptOrigin Function::GetScriptOrigin() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return v8::ScriptOrigin(Local()); + } + auto func = i::Handle::cast(self); if (func->shared()->script()->IsScript()) { i::Handle script(i::Script::cast(func->shared()->script())); return GetScriptOriginForScript(func->GetIsolate(), script); @@ -4424,7 +4481,11 @@ const int Function::kLineOffsetNotFound = -1; int Function::GetScriptLineNumber() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return kLineOffsetNotFound; + } + auto func = i::Handle::cast(self); if (func->shared()->script()->IsScript()) { i::Handle script(i::Script::cast(func->shared()->script())); return i::Script::GetLineNumber(script, func->shared()->start_position()); @@ -4434,7 +4495,11 @@ int Function::GetScriptLineNumber() const { int Function::GetScriptColumnNumber() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return kLineOffsetNotFound; + } + auto func = i::Handle::cast(self); if (func->shared()->script()->IsScript()) { i::Handle script(i::Script::cast(func->shared()->script())); return i::Script::GetColumnNumber(script, func->shared()->start_position()); @@ -4444,13 +4509,21 @@ int Function::GetScriptColumnNumber() const { bool Function::IsBuiltin() const { - i::Handle func = Utils::OpenHandle(this); - return func->IsBuiltin(); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return false; + } + auto func = i::Handle::cast(self); + return func->shared()->IsBuiltin(); } int Function::ScriptId() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return v8::UnboundScript::kNoScriptId; + } + auto func = i::Handle::cast(self); if (!func->shared()->script()->IsScript()) { return v8::UnboundScript::kNoScriptId; } @@ -4460,16 +4533,19 @@ int Function::ScriptId() const { Local Function::GetBoundFunction() const { - i::Handle func = Utils::OpenHandle(this); + auto self = Utils::OpenHandle(this); + if (!self->IsJSFunction()) { + return v8::Undefined(reinterpret_cast(self->GetIsolate())); + } + auto func = i::Handle::cast(self); if (!func->shared()->bound()) { return v8::Undefined(reinterpret_cast(func->GetIsolate())); } - i::Handle bound_args = i::Handle( - i::FixedArray::cast(func->function_bindings())); - i::Handle original( - bound_args->get(i::JSFunction::kBoundFunctionIndex), - func->GetIsolate()); - return Utils::ToLocal(i::Handle::cast(original)); + i::Handle bound_args = i::Handle( + i::BindingsArray::cast(func->function_bindings())); + i::Handle original(bound_args->bound_function(), + func->GetIsolate()); + return Utils::CallableToLocal(i::Handle::cast(original)); } @@ -5178,6 +5254,11 @@ Local Symbol::Name() const { } +Local Private::Name() const { + return reinterpret_cast(this)->Name(); +} + + double Number::Value() const { i::Handle obj = Utils::OpenHandle(this); return obj->Number(); @@ -6047,6 +6128,8 @@ REGEXP_FLAG_ASSERT_EQ(kNone, NONE); REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL); REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE); REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE); +REGEXP_FLAG_ASSERT_EQ(kSticky, STICKY); +REGEXP_FLAG_ASSERT_EQ(kUnicode, UNICODE_ESCAPES); #undef REGEXP_FLAG_ASSERT_EQ v8::RegExp::Flags v8::RegExp::GetFlags() const { @@ -6750,7 +6833,8 @@ Local v8::Symbol::New(Isolate* isolate, Local name) { static i::Handle SymbolFor(i::Isolate* isolate, i::Handle name, - i::Handle part) { + i::Handle part, + bool private_symbol) { i::Handle registry = isolate->GetSymbolRegistry(); i::Handle symbols = i::Handle::cast( @@ -6759,7 +6843,10 @@ static i::Handle SymbolFor(i::Isolate* isolate, i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked(); if (!symbol->IsSymbol()) { DCHECK(symbol->IsUndefined()); - symbol = isolate->factory()->NewSymbol(); + if (private_symbol) + symbol = isolate->factory()->NewPrivateSymbol(); + else + symbol = isolate->factory()->NewSymbol(); i::Handle::cast(symbol)->set_name(*name); i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert(); } @@ -6771,7 +6858,7 @@ Local v8::Symbol::For(Isolate* isolate, Local name) { i::Isolate* i_isolate = reinterpret_cast(isolate); i::Handle i_name = Utils::OpenHandle(*name); i::Handle part = i_isolate->factory()->for_string(); - return Utils::ToLocal(SymbolFor(i_isolate, i_name, part)); + return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false)); } @@ -6779,7 +6866,7 @@ Local v8::Symbol::ForApi(Isolate* isolate, Local name) { i::Isolate* i_isolate = reinterpret_cast(isolate); i::Handle i_name = Utils::OpenHandle(*name); i::Handle part = i_isolate->factory()->for_api_string(); - return Utils::ToLocal(SymbolFor(i_isolate, i_name, part)); + return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false)); } @@ -6801,6 +6888,33 @@ Local v8::Symbol::GetToStringTag(Isolate* isolate) { } +Local v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) { + i::Isolate* i_isolate = reinterpret_cast(isolate); + return Utils::ToLocal(i_isolate->factory()->is_concat_spreadable_symbol()); +} + + +Local v8::Private::New(Isolate* isolate, Local name) { + i::Isolate* i_isolate = reinterpret_cast(isolate); + LOG_API(i_isolate, "Private::New()"); + ENTER_V8(i_isolate); + i::Handle symbol = i_isolate->factory()->NewPrivateSymbol(); + if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name)); + Local result = Utils::ToLocal(symbol); + return v8::Local(reinterpret_cast(*result)); +} + + +Local v8::Private::ForApi(Isolate* isolate, Local name) { + i::Isolate* i_isolate = reinterpret_cast(isolate); + i::Handle i_name = Utils::OpenHandle(*name); + i::Handle part = i_isolate->factory()->private_api_string(); + Local result = + Utils::ToLocal(SymbolFor(i_isolate, i_name, part, true)); + return v8::Local(reinterpret_cast(*result)); +} + + Local v8::Number::New(Isolate* isolate, double value) { i::Isolate* internal_isolate = reinterpret_cast(isolate); if (std::isnan(value)) { @@ -7175,6 +7289,7 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) { heap_statistics->total_available_size_ = heap->Available(); heap_statistics->used_heap_size_ = heap->SizeOfObjects(); heap_statistics->heap_size_limit_ = heap->MaxReserved(); + heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage(); } @@ -7369,6 +7484,18 @@ int Isolate::ContextDisposedNotification(bool dependant_context) { } +void Isolate::IsolateInForegroundNotification() { + i::Isolate* isolate = reinterpret_cast(this); + return isolate->heap()->SetOptimizeForLatency(); +} + + +void Isolate::IsolateInBackgroundNotification() { + i::Isolate* isolate = reinterpret_cast(this); + return isolate->heap()->SetOptimizeForMemoryUsage(); +} + + void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options, JitCodeEventHandler event_handler) { i::Isolate* isolate = reinterpret_cast(this); @@ -7472,10 +7599,10 @@ class VisitorAdapter : public i::ObjectVisitor { public: explicit VisitorAdapter(PersistentHandleVisitor* visitor) : visitor_(visitor) {} - virtual void VisitPointers(i::Object** start, i::Object** end) { + void VisitPointers(i::Object** start, i::Object** end) override { UNREACHABLE(); } - virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) { + void VisitEmbedderReference(i::Object** p, uint16_t class_id) override { Value* value = ToApi(i::Handle(p)); visitor_->VisitPersistentHandle( reinterpret_cast*>(&value), class_id); @@ -7504,6 +7631,15 @@ void Isolate::VisitHandlesForPartialDependence( } +void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) { + i::Isolate* isolate = reinterpret_cast(this); + i::DisallowHeapAllocation no_allocation; + VisitorAdapter visitor_adapter(visitor); + isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds( + &visitor_adapter); +} + + String::Utf8Value::Utf8Value(v8::Local obj) : str_(NULL), length_(0) { if (obj.IsEmpty()) return; @@ -7679,7 +7815,7 @@ MaybeLocal Debug::GetMirror(Local context, i::Handle debug(isolate_debug->debug_context()->global_object()); auto name = isolate->factory()->NewStringFromStaticChars("MakeMirror"); auto fun_obj = i::Object::GetProperty(debug, name).ToHandleChecked(); - auto v8_fun = Utils::ToLocal(i::Handle::cast(fun_obj)); + auto v8_fun = Utils::CallableToLocal(i::Handle::cast(fun_obj)); const int kArgc = 1; v8::Local argv[kArgc] = {obj}; Local result; diff --git a/deps/v8/src/api.h b/deps/v8/src/api.h index 122927959804bb..08fbd7ee8f389d 100644 --- a/deps/v8/src/api.h +++ b/deps/v8/src/api.h @@ -168,7 +168,7 @@ class RegisteredExtension { V(Symbol, Symbol) \ V(Script, JSFunction) \ V(UnboundScript, SharedFunctionInfo) \ - V(Function, JSFunction) \ + V(Function, JSReceiver) \ V(Message, JSMessageObject) \ V(Context, Context) \ V(External, Object) \ @@ -192,8 +192,6 @@ class Utils { v8::internal::Handle obj); static inline Local ToLocal( v8::internal::Handle obj); - static inline Local ToLocal( - v8::internal::Handle obj); static inline Local ToLocal( v8::internal::Handle obj); static inline Local ToLocal( @@ -269,6 +267,8 @@ class Utils { v8::internal::Handle obj); static inline Local NativeWeakMapToLocal( v8::internal::Handle obj); + static inline Local CallableToLocal( + v8::internal::Handle obj); #define DECLARE_OPEN_HANDLE(From, To) \ static inline v8::internal::Handle \ @@ -349,7 +349,6 @@ inline bool ToLocal(v8::internal::MaybeHandle maybe, MAKE_TO_LOCAL(ToLocal, Context, Context) MAKE_TO_LOCAL(ToLocal, Object, Value) -MAKE_TO_LOCAL(ToLocal, JSFunction, Function) MAKE_TO_LOCAL(ToLocal, Name, Name) MAKE_TO_LOCAL(ToLocal, String, String) MAKE_TO_LOCAL(ToLocal, Symbol, Symbol) @@ -380,6 +379,7 @@ MAKE_TO_LOCAL(IntegerToLocal, Object, Integer) MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32) MAKE_TO_LOCAL(ExternalToLocal, JSObject, External) MAKE_TO_LOCAL(NativeWeakMapToLocal, JSWeakMap, NativeWeakMap) +MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function) #undef MAKE_TO_LOCAL_TYPED_ARRAY #undef MAKE_TO_LOCAL @@ -642,6 +642,7 @@ class Testing { static v8::Testing::StressType stress_type_; }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_API_H_ diff --git a/deps/v8/src/arguments.h b/deps/v8/src/arguments.h index ed995e7f582312..d11a8cd61ee0b1 100644 --- a/deps/v8/src/arguments.h +++ b/deps/v8/src/arguments.h @@ -29,10 +29,13 @@ namespace internal { class Arguments BASE_EMBEDDED { public: Arguments(int length, Object** arguments) - : length_(length), arguments_(arguments) { } + : length_(length), arguments_(arguments) { + DCHECK_GE(length_, 0); + } Object*& operator[] (int index) { - DCHECK(0 <= index && index < length_); + DCHECK_GE(index, 0); + DCHECK_LT(static_cast(index), static_cast(length_)); return *(reinterpret_cast(reinterpret_cast(arguments_) - index * kPointerSize)); } @@ -283,6 +286,7 @@ static Type __RT_impl_##Name(Arguments args, Isolate* isolate) #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \ RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name) -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARGUMENTS_H_ diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h index 8f8956c9e1c7eb..175a21df51b2d5 100644 --- a/deps/v8/src/arm/assembler-arm-inl.h +++ b/deps/v8/src/arm/assembler-arm-inl.h @@ -50,53 +50,11 @@ namespace internal { bool CpuFeatures::SupportsCrankshaft() { return IsSupported(VFP3); } -int Register::NumAllocatableRegisters() { - return kMaxNumAllocatableRegisters; -} - - -int DwVfpRegister::NumRegisters() { +int DoubleRegister::NumRegisters() { return CpuFeatures::IsSupported(VFP32DREGS) ? 32 : 16; } -int DwVfpRegister::NumReservedRegisters() { - return kNumReservedRegisters; -} - - -int DwVfpRegister::NumAllocatableRegisters() { - return NumRegisters() - kNumReservedRegisters; -} - - -// static -int DwVfpRegister::NumAllocatableAliasedRegisters() { - return LowDwVfpRegister::kMaxNumLowRegisters - kNumReservedRegisters; -} - - -int DwVfpRegister::ToAllocationIndex(DwVfpRegister reg) { - DCHECK(!reg.is(kDoubleRegZero)); - DCHECK(!reg.is(kScratchDoubleReg)); - if (reg.code() > kDoubleRegZero.code()) { - return reg.code() - kNumReservedRegisters; - } - return reg.code(); -} - - -DwVfpRegister DwVfpRegister::FromAllocationIndex(int index) { - DCHECK(index >= 0 && index < NumAllocatableRegisters()); - DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() == - kNumReservedRegisters - 1); - if (index >= kDoubleRegZero.code()) { - return from_code(index + kNumReservedRegisters); - } - return from_code(index); -} - - void RelocInfo::apply(intptr_t delta) { if (RelocInfo::IsInternalReference(rmode_)) { // absolute code pointer inside code object moves with the code object. @@ -666,6 +624,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool, } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index 50c707d2a0741c..e7b619debb8317 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -52,6 +52,14 @@ namespace internal { // snapshot. static unsigned CpuFeaturesImpliedByCompiler() { unsigned answer = 0; +#ifdef CAN_USE_ARMV8_INSTRUCTIONS + if (FLAG_enable_armv8) { + answer |= 1u << ARMv8; + // ARMv8 always features VFP and NEON. + answer |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; + answer |= 1u << SUDIV | 1u << MLS; + } +#endif // CAN_USE_ARMV8_INSTRUCTIONS #ifdef CAN_USE_ARMV7_INSTRUCTIONS if (FLAG_enable_armv7) answer |= 1u << ARMv7; #endif // CAN_USE_ARMV7_INSTRUCTIONS @@ -81,6 +89,13 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { #ifndef __arm__ // For the simulator build, use whatever the flags specify. + if (FLAG_enable_armv8) { + supported_ |= 1u << ARMv8; + // ARMv8 always features VFP and NEON. + supported_ |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; + supported_ |= 1u << SUDIV | 1u << MLS; + if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; + } if (FLAG_enable_armv7) { supported_ |= 1u << ARMv7; if (FLAG_enable_vfp3) supported_ |= 1u << VFP3; @@ -154,7 +169,9 @@ void CpuFeatures::PrintTarget() { arm_no_probe = " noprobe"; #endif -#if defined CAN_USE_ARMV7_INSTRUCTIONS +#if defined CAN_USE_ARMV8_INSTRUCTIONS + arm_arch = "arm v8"; +#elif defined CAN_USE_ARMV7_INSTRUCTIONS arm_arch = "arm v7"; #else arm_arch = "arm v6"; @@ -192,13 +209,15 @@ void CpuFeatures::PrintTarget() { void CpuFeatures::PrintFeatures() { printf( - "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d " - "MOVW_MOVT_IMMEDIATE_LOADS=%d COHERENT_CACHE=%d", + "ARMv8=%d ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d MLS=%d" + "UNALIGNED_ACCESSES=%d MOVW_MOVT_IMMEDIATE_LOADS=%d COHERENT_CACHE=%d", + CpuFeatures::IsSupported(ARMv8), CpuFeatures::IsSupported(ARMv7), CpuFeatures::IsSupported(VFP3), CpuFeatures::IsSupported(VFP32DREGS), CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV), + CpuFeatures::IsSupported(MLS), CpuFeatures::IsSupported(UNALIGNED_ACCESSES), CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS), CpuFeatures::IsSupported(COHERENT_CACHE)); @@ -213,18 +232,6 @@ void CpuFeatures::PrintFeatures() { } -// ----------------------------------------------------------------------------- -// Implementation of DwVfpRegister - -const char* DwVfpRegister::AllocationIndexToString(int index) { - DCHECK(index >= 0 && index < NumAllocatableRegisters()); - DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() == - kNumReservedRegisters - 1); - if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters; - return VFPRegisters::Name(index, true); -} - - // ----------------------------------------------------------------------------- // Implementation of RelocInfo @@ -398,26 +405,26 @@ NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) { // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) // register r is not encoded. const Instr kPushRegPattern = - al | B26 | 4 | NegPreIndex | kRegister_sp_Code * B16; + al | B26 | 4 | NegPreIndex | Register::kCode_sp * B16; // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) // register r is not encoded. const Instr kPopRegPattern = - al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16; + al | B26 | L | 4 | PostIndex | Register::kCode_sp * B16; // ldr rd, [pc, #offset] const Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16; -const Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16; +const Instr kLdrPCImmedPattern = 5 * B24 | L | Register::kCode_pc * B16; // ldr rd, [pp, #offset] const Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16; -const Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16; +const Instr kLdrPpImmedPattern = 5 * B24 | L | Register::kCode_r8 * B16; // ldr rd, [pp, rn] const Instr kLdrPpRegMask = 15 * B24 | 7 * B20 | 15 * B16; -const Instr kLdrPpRegPattern = 7 * B24 | L | kRegister_r8_Code * B16; +const Instr kLdrPpRegPattern = 7 * B24 | L | Register::kCode_r8 * B16; // vldr dd, [pc, #offset] const Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8; -const Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8; +const Instr kVldrDPCPattern = 13 * B24 | L | Register::kCode_pc * B16 | 11 * B8; // vldr dd, [pp, #offset] const Instr kVldrDPpMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8; -const Instr kVldrDPpPattern = 13 * B24 | L | kRegister_r8_Code * B16 | 11 * B8; +const Instr kVldrDPpPattern = 13 * B24 | L | Register::kCode_r8 * B16 | 11 * B8; // blxcc rm const Instr kBlxRegMask = 15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4; @@ -444,13 +451,13 @@ const Instr kAndBicFlip = 0xe * B21; // A mask for the Rd register for push, pop, ldr, str instructions. const Instr kLdrRegFpOffsetPattern = - al | B26 | L | Offset | kRegister_fp_Code * B16; + al | B26 | L | Offset | Register::kCode_fp * B16; const Instr kStrRegFpOffsetPattern = - al | B26 | Offset | kRegister_fp_Code * B16; + al | B26 | Offset | Register::kCode_fp * B16; const Instr kLdrRegFpNegOffsetPattern = - al | B26 | L | NegOffset | kRegister_fp_Code * B16; + al | B26 | L | NegOffset | Register::kCode_fp * B16; const Instr kStrRegFpNegOffsetPattern = - al | B26 | NegOffset | kRegister_fp_Code * B16; + al | B26 | NegOffset | Register::kCode_fp * B16; const Instr kLdrStrInstrTypeMask = 0xffff0000; @@ -626,21 +633,21 @@ Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) { Register Assembler::GetRd(Instr instr) { Register reg; - reg.code_ = Instruction::RdValue(instr); + reg.reg_code = Instruction::RdValue(instr); return reg; } Register Assembler::GetRn(Instr instr) { Register reg; - reg.code_ = Instruction::RnValue(instr); + reg.reg_code = Instruction::RnValue(instr); return reg; } Register Assembler::GetRm(Instr instr) { Register reg; - reg.code_ = Instruction::RmValue(instr); + reg.reg_code = Instruction::RmValue(instr); return reg; } diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h index 1d1cc485d5064b..db6adae57a4b4a 100644 --- a/deps/v8/src/arm/assembler-arm.h +++ b/deps/v8/src/arm/assembler-arm.h @@ -45,11 +45,35 @@ #include "src/arm/constants-arm.h" #include "src/assembler.h" -#include "src/compiler.h" namespace v8 { namespace internal { +// clang-format off +#define GENERAL_REGISTERS(V) \ + V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ + V(r8) V(r9) V(r10) V(fp) V(ip) V(sp) V(lr) V(pc) + +#define ALLOCATABLE_GENERAL_REGISTERS(V) \ + V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) V(r8) + +#define DOUBLE_REGISTERS(V) \ + V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ + V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \ + V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ + V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) + +#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ + V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ + V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) \ + V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ + V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) + +#define ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(V) \ + V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ + V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) \ +// clang-format on + // CPU Registers. // // 1) We would prefer to use an enum, but enum values are assignment- @@ -71,190 +95,123 @@ namespace internal { // mode. This way we get the compile-time error checking in debug mode // and best performance in optimized code. -// These constants are used in several locations, including static initializers -const int kRegister_no_reg_Code = -1; -const int kRegister_r0_Code = 0; -const int kRegister_r1_Code = 1; -const int kRegister_r2_Code = 2; -const int kRegister_r3_Code = 3; -const int kRegister_r4_Code = 4; -const int kRegister_r5_Code = 5; -const int kRegister_r6_Code = 6; -const int kRegister_r7_Code = 7; -const int kRegister_r8_Code = 8; -const int kRegister_r9_Code = 9; -const int kRegister_r10_Code = 10; -const int kRegister_fp_Code = 11; -const int kRegister_ip_Code = 12; -const int kRegister_sp_Code = 13; -const int kRegister_lr_Code = 14; -const int kRegister_pc_Code = 15; - -// Core register struct Register { - static const int kNumRegisters = 16; - static const int kMaxNumAllocatableRegisters = - FLAG_enable_embedded_constant_pool ? 8 : 9; - static const int kSizeInBytes = 4; - - inline static int NumAllocatableRegisters(); - - static int ToAllocationIndex(Register reg) { - DCHECK(reg.code() < kMaxNumAllocatableRegisters); - return reg.code(); - } - - static Register FromAllocationIndex(int index) { - DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); - return from_code(index); - } + enum Code { +#define REGISTER_CODE(R) kCode_##R, + GENERAL_REGISTERS(REGISTER_CODE) +#undef REGISTER_CODE + kAfterLast, + kCode_no_reg = -1 + }; - static const char* AllocationIndexToString(int index) { - DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); - const char* const names[] = { - "r0", - "r1", - "r2", - "r3", - "r4", - "r5", - "r6", - "r7", - "r8", - }; - if (FLAG_enable_embedded_constant_pool && (index >= 7)) { - return names[index + 1]; - } - return names[index]; - } + static const int kNumRegisters = Code::kAfterLast; static Register from_code(int code) { - Register r = { code }; + DCHECK(code >= 0); + DCHECK(code < kNumRegisters); + Register r = {code}; return r; } - - bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } - bool is(Register reg) const { return code_ == reg.code_; } + const char* ToString(); + bool IsAllocatable() const; + bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } + bool is(Register reg) const { return reg_code == reg.reg_code; } int code() const { DCHECK(is_valid()); - return code_; + return reg_code; } int bit() const { DCHECK(is_valid()); - return 1 << code_; + return 1 << reg_code; } - void set_code(int code) { - code_ = code; + reg_code = code; DCHECK(is_valid()); } // Unfortunately we can't make this private in a struct. - int code_; + int reg_code; }; -const Register no_reg = { kRegister_no_reg_Code }; - -const Register r0 = { kRegister_r0_Code }; -const Register r1 = { kRegister_r1_Code }; -const Register r2 = { kRegister_r2_Code }; -const Register r3 = { kRegister_r3_Code }; -const Register r4 = { kRegister_r4_Code }; -const Register r5 = { kRegister_r5_Code }; -const Register r6 = { kRegister_r6_Code }; -// Used as context register. -const Register r7 = {kRegister_r7_Code}; -// Used as constant pool pointer register if FLAG_enable_embedded_constant_pool. -const Register r8 = { kRegister_r8_Code }; -// Used as lithium codegen scratch register. -const Register r9 = { kRegister_r9_Code }; -// Used as roots register. -const Register r10 = { kRegister_r10_Code }; -const Register fp = { kRegister_fp_Code }; -const Register ip = { kRegister_ip_Code }; -const Register sp = { kRegister_sp_Code }; -const Register lr = { kRegister_lr_Code }; -const Register pc = { kRegister_pc_Code }; +// r7: context register +// r8: constant pool pointer register if FLAG_enable_embedded_constant_pool. +// r9: lithium scratch +#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; +GENERAL_REGISTERS(DECLARE_REGISTER) +#undef DECLARE_REGISTER +const Register no_reg = {Register::kCode_no_reg}; // Single word VFP register. struct SwVfpRegister { static const int kSizeInBytes = 4; - bool is_valid() const { return 0 <= code_ && code_ < 32; } - bool is(SwVfpRegister reg) const { return code_ == reg.code_; } + bool is_valid() const { return 0 <= reg_code && reg_code < 32; } + bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; } int code() const { DCHECK(is_valid()); - return code_; + return reg_code; } int bit() const { DCHECK(is_valid()); - return 1 << code_; + return 1 << reg_code; } void split_code(int* vm, int* m) const { DCHECK(is_valid()); - *m = code_ & 0x1; - *vm = code_ >> 1; + *m = reg_code & 0x1; + *vm = reg_code >> 1; } - int code_; + int reg_code; }; // Double word VFP register. -struct DwVfpRegister { - static const int kMaxNumRegisters = 32; +struct DoubleRegister { + enum Code { +#define REGISTER_CODE(R) kCode_##R, + DOUBLE_REGISTERS(REGISTER_CODE) +#undef REGISTER_CODE + kAfterLast, + kCode_no_reg = -1 + }; + + static const int kMaxNumRegisters = Code::kAfterLast; + + inline static int NumRegisters(); + // A few double registers are reserved: one as a scratch register and one to // hold 0.0, that does not fit in the immediate field of vmov instructions. // d14: 0.0 // d15: scratch register. - static const int kNumReservedRegisters = 2; - static const int kMaxNumAllocatableRegisters = kMaxNumRegisters - - kNumReservedRegisters; static const int kSizeInBytes = 8; - // Note: the number of registers can be different at snapshot and run-time. - // Any code included in the snapshot must be able to run both with 16 or 32 - // registers. - inline static int NumRegisters(); - inline static int NumReservedRegisters(); - inline static int NumAllocatableRegisters(); - - // TODO(turbofan): This is a temporary work-around required because our - // register allocator does not yet support the aliasing of single/double - // registers on ARM. - inline static int NumAllocatableAliasedRegisters(); - - inline static int ToAllocationIndex(DwVfpRegister reg); - static const char* AllocationIndexToString(int index); - inline static DwVfpRegister FromAllocationIndex(int index); - - static DwVfpRegister from_code(int code) { - DwVfpRegister r = { code }; - return r; - } - - bool is_valid() const { - return 0 <= code_ && code_ < kMaxNumRegisters; - } - bool is(DwVfpRegister reg) const { return code_ == reg.code_; } + const char* ToString(); + bool IsAllocatable() const; + bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } + bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } int code() const { DCHECK(is_valid()); - return code_; + return reg_code; } int bit() const { DCHECK(is_valid()); - return 1 << code_; + return 1 << reg_code; + } + + static DoubleRegister from_code(int code) { + DoubleRegister r = {code}; + return r; } void split_code(int* vm, int* m) const { DCHECK(is_valid()); - *m = (code_ & 0x10) >> 4; - *vm = code_ & 0x0F; + *m = (reg_code & 0x10) >> 4; + *vm = reg_code & 0x0F; } - int code_; + int reg_code; }; -typedef DwVfpRegister DoubleRegister; +typedef DoubleRegister DwVfpRegister; // Double word VFP register d0-15. @@ -262,7 +219,7 @@ struct LowDwVfpRegister { public: static const int kMaxNumLowRegisters = 16; operator DwVfpRegister() const { - DwVfpRegister r = { code_ }; + DwVfpRegister r = { reg_code }; return r; } static LowDwVfpRegister from_code(int code) { @@ -271,30 +228,30 @@ struct LowDwVfpRegister { } bool is_valid() const { - return 0 <= code_ && code_ < kMaxNumLowRegisters; + return 0 <= reg_code && reg_code < kMaxNumLowRegisters; } - bool is(DwVfpRegister reg) const { return code_ == reg.code_; } - bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; } + bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; } + bool is(LowDwVfpRegister reg) const { return reg_code == reg.reg_code; } int code() const { DCHECK(is_valid()); - return code_; + return reg_code; } SwVfpRegister low() const { SwVfpRegister reg; - reg.code_ = code_ * 2; + reg.reg_code = reg_code * 2; DCHECK(reg.is_valid()); return reg; } SwVfpRegister high() const { SwVfpRegister reg; - reg.code_ = (code_ * 2) + 1; + reg.reg_code = (reg_code * 2) + 1; DCHECK(reg.is_valid()); return reg; } - int code_; + int reg_code; }; @@ -308,21 +265,21 @@ struct QwNeonRegister { } bool is_valid() const { - return (0 <= code_) && (code_ < kMaxNumRegisters); + return (0 <= reg_code) && (reg_code < kMaxNumRegisters); } - bool is(QwNeonRegister reg) const { return code_ == reg.code_; } + bool is(QwNeonRegister reg) const { return reg_code == reg.reg_code; } int code() const { DCHECK(is_valid()); - return code_; + return reg_code; } void split_code(int* vm, int* m) const { DCHECK(is_valid()); - int encoded_code = code_ << 1; + int encoded_code = reg_code << 1; *m = (encoded_code & 0x10) >> 4; *vm = encoded_code & 0x0F; } - int code_; + int reg_code; }; @@ -427,19 +384,19 @@ const QwNeonRegister q15 = { 15 }; // Coprocessor register struct CRegister { - bool is_valid() const { return 0 <= code_ && code_ < 16; } - bool is(CRegister creg) const { return code_ == creg.code_; } + bool is_valid() const { return 0 <= reg_code && reg_code < 16; } + bool is(CRegister creg) const { return reg_code == creg.reg_code; } int code() const { DCHECK(is_valid()); - return code_; + return reg_code; } int bit() const { DCHECK(is_valid()); - return 1 << code_; + return 1 << reg_code; } // Unfortunately we can't make this private in a struct. - int code_; + int reg_code; }; @@ -1667,6 +1624,7 @@ class EnsureSpace BASE_EMBEDDED { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_ASSEMBLER_ARM_H_ diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index ea2c92e6407061..4464816f725ed6 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -22,11 +22,12 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- r0 : number of arguments excluding receiver - // -- r1 : called function (only guaranteed when - // extra_args requires it) + // (only guaranteed when the called function + // is not marked as DontAdaptArguments) + // -- r1 : called function // -- sp[0] : last argument // -- ... - // -- sp[4 * (argc - 1)] : first argument (argc == r0) + // -- sp[4 * (argc - 1)] : first argument // -- sp[4 * argc] : receiver // ----------------------------------- __ AssertFunction(r1); @@ -48,8 +49,17 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, } // JumpToExternalReference expects r0 to contain the number of arguments - // including the receiver and the extra arguments. + // including the receiver and the extra arguments. But r0 is only valid + // if the called function is marked as DontAdaptArguments, otherwise we + // need to load the argument count from the SharedFunctionInfo. + __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); + __ ldr(r2, + FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); + __ SmiUntag(r2); + __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); + __ mov(r0, r2, LeaveCC, ne); __ add(r0, r0, Operand(num_extra_args + 1)); + __ JumpToExternalReference(ExternalReference(id, masm->isolate())); } @@ -61,8 +71,7 @@ static void GenerateLoadInternalArrayFunction(MacroAssembler* masm, __ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ ldr(result, - FieldMemOperand(result, GlobalObject::kNativeContextOffset)); + __ ldr(result, FieldMemOperand(result, JSGlobalObject::kNativeContextOffset)); // Load the InternalArray function from the native context. __ ldr(result, MemOperand(result, @@ -77,8 +86,7 @@ static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { __ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ ldr(result, - FieldMemOperand(result, GlobalObject::kNativeContextOffset)); + __ ldr(result, FieldMemOperand(result, JSGlobalObject::kNativeContextOffset)); // Load the Array function from the native context. __ ldr(result, MemOperand(result, @@ -203,39 +211,42 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r0 : number of arguments // -- r1 : constructor function + // -- r3 : original constructor // -- lr : return address // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) // -- sp[argc * 4] : receiver // ----------------------------------- - // 1. Load the first argument into r0 and get rid of the rest (including the + // 1. Load the first argument into r2 and get rid of the rest (including the // receiver). { Label no_arguments, done; __ sub(r0, r0, Operand(1), SetCC); __ b(lo, &no_arguments); - __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); + __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); __ Drop(2); __ b(&done); __ bind(&no_arguments); - __ LoadRoot(r0, Heap::kempty_stringRootIndex); + __ LoadRoot(r2, Heap::kempty_stringRootIndex); __ Drop(1); __ bind(&done); } - // 2. Make sure r0 is a string. + // 2. Make sure r2 is a string. { Label convert, done_convert; - __ JumpIfSmi(r0, &convert); - __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE); + __ JumpIfSmi(r2, &convert); + __ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE); __ b(lo, &done_convert); __ bind(&convert); { FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); ToStringStub stub(masm->isolate()); - __ Push(r1); + __ Push(r1, r3); + __ Move(r0, r2); __ CallStub(&stub); - __ Pop(r1); + __ Move(r2, r0); + __ Pop(r1, r3); } __ bind(&done_convert); } @@ -243,13 +254,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { // 3. Allocate a JSValue wrapper for the string. { // ----------- S t a t e ------------- - // -- r0 : the first argument + // -- r2 : the first argument // -- r1 : constructor function + // -- r3 : original constructor // -- lr : return address // ----------------------------------- - Label allocate, done_allocate; - __ Move(r2, r0); + Label allocate, done_allocate, rt_call; + + // Fall back to runtime if the original constructor and function differ. + __ cmp(r1, r3); + __ b(ne, &rt_call); + __ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT); __ bind(&done_allocate); @@ -273,6 +289,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { __ Pop(r1, r2); } __ b(&done_allocate); + + // Fallback to the runtime to create new object. + __ bind(&rt_call); + { + FrameScope scope(masm, StackFrame::INTERNAL); + __ Push(r1, r2); + __ Push(r1, r3); // constructor function, original constructor + __ CallRuntime(Runtime::kNewObject, 2); + __ Pop(r1, r2); + } + __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); + __ Ret(); } } @@ -360,17 +388,23 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ tst(r2, r2); __ b(ne, &rt_call); - // Fall back to runtime if the original constructor and function differ. - __ cmp(r1, r3); + // Verify that the original constructor is a JSFunction. + __ CompareObjectType(r3, r5, r4, JS_FUNCTION_TYPE); __ b(ne, &rt_call); // Load the initial map and verify that it is in fact a map. - // r1: constructor function - __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); + // r3: original constructor + __ ldr(r2, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset)); __ JumpIfSmi(r2, &rt_call); __ CompareObjectType(r2, r5, r4, MAP_TYPE); __ b(ne, &rt_call); + // Fall back to runtime if the expected base constructor and base + // constructor differ. + __ ldr(r5, FieldMemOperand(r2, Map::kConstructorOrBackPointerOffset)); + __ cmp(r1, r5); + __ b(ne, &rt_call); + // Check that the constructor is not constructing a JSFunction (see // comments in Runtime_NewObject in runtime.cc). In which case the // initial map's instance type would be JS_FUNCTION_TYPE. @@ -393,9 +427,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ cmp(r3, Operand(Map::kSlackTrackingCounterEnd)); __ b(ne, &allocate); - __ push(r1); + __ Push(r1, r2); - __ Push(r2, r1); // r1 = constructor + __ push(r2); // r2 = intial map __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); __ pop(r2); @@ -490,8 +524,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // r3: original constructor __ bind(&rt_call); - __ push(r1); // argument 2/1: constructor function - __ push(r3); // argument 3/2: original constructor + __ push(r1); // constructor function + __ push(r3); // original constructor __ CallRuntime(Runtime::kNewObject, 2); __ mov(r4, r0); @@ -896,21 +930,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // - Support profiler (specifically profiling_counter). // - Call ProfileEntryHookStub when isolate has a function_entry_hook. // - Allow simulator stop operations if FLAG_stop_at is set. - // - Deal with sloppy mode functions which need to replace the - // receiver with the global proxy when called as functions (without an - // explicit receiver object). // - Code aging of the BytecodeArray object. - // - Supporting FLAG_trace. - // - // The following items are also not done here, and will probably be done using - // explicit bytecodes instead: - // - Allocating a new local context if applicable. - // - Setting up a local binding to the this function, which is used in - // derived constructors with super calls. - // - Setting new.target if required. - // - Dealing with REST parameters (only if - // https://codereview.chromium.org/1235153006 doesn't land by then). - // - Dealing with argument objects. // Perform stack guard check. { @@ -918,7 +938,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ LoadRoot(ip, Heap::kStackLimitRootIndex); __ cmp(sp, Operand(ip)); __ b(hs, &ok); + __ push(kInterpreterBytecodeArrayRegister); __ CallRuntime(Runtime::kStackGuard, 0); + __ pop(kInterpreterBytecodeArrayRegister); __ bind(&ok); } @@ -966,6 +988,66 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { } +static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index, + Register limit, Register scratch) { + Label loop_header, loop_check; + __ b(al, &loop_check); + __ bind(&loop_header); + __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex)); + __ push(scratch); + __ bind(&loop_check); + __ cmp(index, limit); + __ b(gt, &loop_header); +} + + +// static +void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { + // ----------- S t a t e ------------- + // -- r0 : the number of arguments (not including the receiver) + // -- r2 : the address of the first argument to be pushed. Subsequent + // arguments should be consecutive above this, in the same order as + // they are to be pushed onto the stack. + // -- r1 : the target to call (can be any Object). + // ----------------------------------- + + // Find the address of the last argument. + __ add(r3, r0, Operand(1)); // Add one for receiver. + __ mov(r3, Operand(r3, LSL, kPointerSizeLog2)); + __ sub(r3, r2, r3); + + // Push the arguments. + Generate_InterpreterPushArgs(masm, r2, r3, r4); + + // Call the target. + __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); +} + + +// static +void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { + // ----------- S t a t e ------------- + // -- r0 : argument count (not including receiver) + // -- r3 : original constructor + // -- r1 : constructor to call + // -- r2 : address of the first argument + // ----------------------------------- + + // Find the address of the last argument. + __ mov(r4, Operand(r0, LSL, kPointerSizeLog2)); + __ sub(r4, r2, r4); + + // Push a slot for the receiver to be constructed. + __ push(r0); + + // Push the arguments. + Generate_InterpreterPushArgs(masm, r2, r4, r5); + + // Call the constructor with r0, r1, and r3 unmodified. + __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { CallRuntimePassFunction(masm, Runtime::kCompileLazy); GenerateTailCallToReturnedCode(masm); @@ -1483,70 +1565,82 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { // static -void Builtins::Generate_CallFunction(MacroAssembler* masm) { +void Builtins::Generate_CallFunction(MacroAssembler* masm, + ConvertReceiverMode mode) { // ----------- S t a t e ------------- // -- r0 : the number of arguments (not including the receiver) // -- r1 : the function to call (checked to be a JSFunction) // ----------------------------------- - - Label convert, convert_global_proxy, convert_to_object, done_convert; __ AssertFunction(r1); - // TODO(bmeurer): Throw a TypeError if function's [[FunctionKind]] internal - // slot is "classConstructor". + + // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) + // Check that the function is not a "classConstructor". + Label class_constructor; + __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); + __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset)); + __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte)); + __ b(ne, &class_constructor); + // Enter the context of the function; ToObject has to run in the function // context, and we also need to take the global proxy from the function // context in case of conversion. - // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == SharedFunctionInfo::kStrictModeByteOffset); __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); - __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); // We need to convert the receiver for non-native sloppy mode functions. + Label done_convert; __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset)); __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); __ b(ne, &done_convert); { - __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); - // ----------- S t a t e ------------- // -- r0 : the number of arguments (not including the receiver) // -- r1 : the function to call (checked to be a JSFunction) // -- r2 : the shared function info. - // -- r3 : the receiver // -- cp : the function context. // ----------------------------------- - Label convert_receiver; - __ JumpIfSmi(r3, &convert_to_object); - STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); - __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); - __ b(hs, &done_convert); - __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex, &convert_global_proxy); - __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object); - __ bind(&convert_global_proxy); - { + if (mode == ConvertReceiverMode::kNullOrUndefined) { // Patch receiver to global proxy. __ LoadGlobalProxy(r3); + } else { + Label convert_to_object, convert_receiver; + __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); + __ JumpIfSmi(r3, &convert_to_object); + STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); + __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); + __ b(hs, &done_convert); + if (mode != ConvertReceiverMode::kNotNullOrUndefined) { + Label convert_global_proxy; + __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex, + &convert_global_proxy); + __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object); + __ bind(&convert_global_proxy); + { + // Patch receiver to global proxy. + __ LoadGlobalProxy(r3); + } + __ b(&convert_receiver); + } + __ bind(&convert_to_object); + { + // Convert receiver using ToObject. + // TODO(bmeurer): Inline the allocation here to avoid building the frame + // in the fast case? (fall back to AllocateInNewSpace?) + FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); + __ SmiTag(r0); + __ Push(r0, r1); + __ mov(r0, r3); + ToObjectStub stub(masm->isolate()); + __ CallStub(&stub); + __ mov(r3, r0); + __ Pop(r0, r1); + __ SmiUntag(r0); + } + __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); + __ bind(&convert_receiver); } - __ b(&convert_receiver); - __ bind(&convert_to_object); - { - // Convert receiver using ToObject. - // TODO(bmeurer): Inline the allocation here to avoid building the frame - // in the fast case? (fall back to AllocateInNewSpace?) - FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - __ SmiTag(r0); - __ Push(r0, r1); - __ mov(r0, r3); - ToObjectStub stub(masm->isolate()); - __ CallStub(&stub); - __ mov(r3, r0); - __ Pop(r0, r1); - __ SmiUntag(r0); - } - __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); - __ bind(&convert_receiver); __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); } __ bind(&done_convert); @@ -1565,11 +1659,18 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm) { ParameterCount actual(r0); ParameterCount expected(r2); __ InvokeCode(r3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); + + // The function is a "classConstructor", need to raise an exception. + __ bind(&class_constructor); + { + FrameScope frame(masm, StackFrame::INTERNAL); + __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); + } } // static -void Builtins::Generate_Call(MacroAssembler* masm) { +void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // ----------- S t a t e ------------- // -- r0 : the number of arguments (not including the receiver) // -- r1 : the target to call (can be any Object). @@ -1579,8 +1680,8 @@ void Builtins::Generate_Call(MacroAssembler* masm) { __ JumpIfSmi(r1, &non_callable); __ bind(&non_smi); __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); - __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, - eq); + __ Jump(masm->isolate()->builtins()->CallFunction(mode), + RelocInfo::CODE_TARGET, eq); __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE)); __ b(ne, &non_function); @@ -1601,7 +1702,9 @@ void Builtins::Generate_Call(MacroAssembler* masm) { __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // Let the "call_as_function_delegate" take care of the rest. __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1); - __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); + __ Jump(masm->isolate()->builtins()->CallFunction( + ConvertReceiverMode::kNotNullOrUndefined), + RelocInfo::CODE_TARGET); // 3. Call to something that is not callable. __ bind(&non_callable); @@ -1696,35 +1799,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { } -// static -void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- r0 : the number of arguments (not including the receiver) - // -- r2 : the address of the first argument to be pushed. Subsequent - // arguments should be consecutive above this, in the same order as - // they are to be pushed onto the stack. - // -- r1 : the target to call (can be any Object). - - // Find the address of the last argument. - __ add(r3, r0, Operand(1)); // Add one for receiver. - __ mov(r3, Operand(r3, LSL, kPointerSizeLog2)); - __ sub(r3, r2, r3); - - // Push the arguments. - Label loop_header, loop_check; - __ b(al, &loop_check); - __ bind(&loop_header); - __ ldr(r4, MemOperand(r2, -kPointerSize, PostIndex)); - __ push(r4); - __ bind(&loop_check); - __ cmp(r2, r3); - __ b(gt, &loop_header); - - // Call the target. - __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); -} - - void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r0 : actual number of arguments diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index a8a4b5f5ac5f24..c9207254773cff 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -974,14 +974,21 @@ void CEntryStub::Generate(MacroAssembler* masm) { // fp: frame pointer (restored after C call) // sp: stack pointer (restored as callee's sp after C call) // cp: current context (C callee-saved) - + // + // If argv_in_register(): + // r2: pointer to the first argument ProfileEntryHookStub::MaybeCallEntryHook(masm); __ mov(r5, Operand(r1)); - // Compute the argv pointer in a callee-saved register. - __ add(r1, sp, Operand(r0, LSL, kPointerSizeLog2)); - __ sub(r1, r1, Operand(kPointerSize)); + if (argv_in_register()) { + // Move argv into the correct register. + __ mov(r1, Operand(r2)); + } else { + // Compute the argv pointer in a callee-saved register. + __ add(r1, sp, Operand(r0, LSL, kPointerSizeLog2)); + __ sub(r1, r1, Operand(kPointerSize)); + } // Enter the exit frame that transitions from JavaScript to C++. FrameScope scope(masm, StackFrame::MANUAL); @@ -1057,8 +1064,15 @@ void CEntryStub::Generate(MacroAssembler* masm) { // r0:r1: result // sp: stack pointer // fp: frame pointer - // Callee-saved register r4 still holds argc. - __ LeaveExitFrame(save_doubles(), r4, true); + Register argc; + if (argv_in_register()) { + // We don't want to pop arguments so set argc to no_reg. + argc = no_reg; + } else { + // Callee-saved register r4 still holds argc. + argc = r4; + } + __ LeaveExitFrame(save_doubles(), argc, true); __ mov(pc, lr); // Handling of exception. @@ -1587,7 +1601,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset)); + __ ldr(r4, FieldMemOperand(r4, JSGlobalObject::kNativeContextOffset)); __ cmp(r6, Operand::Zero()); __ ldr(r4, MemOperand(r4, kNormalOffset), eq); __ ldr(r4, MemOperand(r4, kAliasedOffset), ne); @@ -1780,7 +1794,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { // Get the arguments boilerplate from the current native context. __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset)); + __ ldr(r4, FieldMemOperand(r4, JSGlobalObject::kNativeContextOffset)); __ ldr(r4, MemOperand( r4, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX))); @@ -2365,99 +2379,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { } -static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { - // Do not transform the receiver for strict mode functions. - __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); - __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); - __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + - kSmiTagSize))); - __ b(ne, cont); - - // Do not transform the receiver for native (Compilerhints already in r3). - __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); - __ b(ne, cont); -} - - -static void EmitSlowCase(MacroAssembler* masm, int argc) { - __ mov(r0, Operand(argc)); - __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); -} - - -static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { - // Wrap the receiver and patch it back onto the stack. - { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); - __ push(r1); - __ mov(r0, r3); - ToObjectStub stub(masm->isolate()); - __ CallStub(&stub); - __ pop(r1); - } - __ str(r0, MemOperand(sp, argc * kPointerSize)); - __ jmp(cont); -} - - -static void CallFunctionNoFeedback(MacroAssembler* masm, - int argc, bool needs_checks, - bool call_as_method) { - // r1 : the function to call - Label slow, wrap, cont; - - if (needs_checks) { - // Check that the function is really a JavaScript function. - // r1: pushed function (to be verified) - __ JumpIfSmi(r1, &slow); - - // Goto slow case if we do not have a function. - __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); - __ b(ne, &slow); - } - - // Fast-case: Invoke the function now. - // r1: pushed function - ParameterCount actual(argc); - - if (call_as_method) { - if (needs_checks) { - EmitContinueIfStrictOrNative(masm, &cont); - } - - // Compute the receiver in sloppy mode. - __ ldr(r3, MemOperand(sp, argc * kPointerSize)); - - if (needs_checks) { - __ JumpIfSmi(r3, &wrap); - __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); - __ b(lt, &wrap); - } else { - __ jmp(&wrap); - } - - __ bind(&cont); - } - - __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); - - if (needs_checks) { - // Slow-case: Non-function called. - __ bind(&slow); - EmitSlowCase(masm, argc); - } - - if (call_as_method) { - __ bind(&wrap); - EmitWrapCase(masm, argc, &cont); - } -} - - -void CallFunctionStub::Generate(MacroAssembler* masm) { - CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); -} - - void CallConstructStub::Generate(MacroAssembler* masm) { // r0 : number of arguments // r1 : the function to call @@ -2540,9 +2461,7 @@ void CallICStub::Generate(MacroAssembler* masm) { FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); const int generic_offset = FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); - Label extra_checks_or_miss, slow_start; - Label slow, wrap, cont; - Label have_js_function; + Label extra_checks_or_miss, call; int argc = arg_count(); ParameterCount actual(argc); @@ -2579,34 +2498,15 @@ void CallICStub::Generate(MacroAssembler* masm) { __ add(r3, r3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); __ str(r3, FieldMemOperand(r2, 0)); - __ bind(&have_js_function); - if (CallAsMethod()) { - EmitContinueIfStrictOrNative(masm, &cont); - // Compute the receiver in sloppy mode. - __ ldr(r3, MemOperand(sp, argc * kPointerSize)); - - __ JumpIfSmi(r3, &wrap); - __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); - __ b(lt, &wrap); - - __ bind(&cont); - } - - __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); - - __ bind(&slow); - EmitSlowCase(masm, argc); - - if (CallAsMethod()) { - __ bind(&wrap); - EmitWrapCase(masm, argc, &cont); - } + __ bind(&call); + __ mov(r0, Operand(argc)); + __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); __ bind(&extra_checks_or_miss); Label uninitialized, miss, not_allocation_site; __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); - __ b(eq, &slow_start); + __ b(eq, &call); // Verify that r4 contains an AllocationSite __ ldr(r5, FieldMemOperand(r4, HeapObject::kMapOffset)); @@ -2642,7 +2542,7 @@ void CallICStub::Generate(MacroAssembler* masm) { __ ldr(r4, FieldMemOperand(r2, generic_offset)); __ add(r4, r4, Operand(Smi::FromInt(1))); __ str(r4, FieldMemOperand(r2, generic_offset)); - __ jmp(&slow_start); + __ jmp(&call); __ bind(&uninitialized); @@ -2681,23 +2581,14 @@ void CallICStub::Generate(MacroAssembler* masm) { __ Pop(r1); } - __ jmp(&have_js_function); + __ jmp(&call); // We are here because tracing is on or we encountered a MISS case we can't // handle here. __ bind(&miss); GenerateMiss(masm); - // the slow case - __ bind(&slow_start); - // Check that the function is really a JavaScript function. - // r1: pushed function (to be verified) - __ JumpIfSmi(r1, &slow); - - // Goto slow case if we do not have a function. - __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); - __ b(ne, &slow); - __ jmp(&have_js_function); + __ jmp(&call); } @@ -2843,7 +2734,7 @@ void StringCharFromCodeGenerator::GenerateSlow( __ bind(&slow_case_); call_helper.BeforeCall(masm); __ push(code_); - __ CallRuntime(Runtime::kCharFromCode, 1); + __ CallRuntime(Runtime::kStringCharFromCode, 1); __ Move(result_, r0); call_helper.AfterCall(masm); __ jmp(&exit_); @@ -3154,6 +3045,21 @@ void ToNumberStub::Generate(MacroAssembler* masm) { } +void ToLengthStub::Generate(MacroAssembler* masm) { + // The ToLength stub takes one argument in r0. + Label not_smi; + __ JumpIfNotSmi(r0, ¬_smi); + STATIC_ASSERT(kSmiTag == 0); + __ tst(r0, r0); + __ mov(r0, Operand(0), LeaveCC, lt); + __ Ret(); + __ bind(¬_smi); + + __ push(r0); // Push argument. + __ TailCallRuntime(Runtime::kToLength, 1, 1); +} + + void ToStringStub::Generate(MacroAssembler* masm) { // The ToString stub takes one argument in r0. Label is_number; diff --git a/deps/v8/src/arm/code-stubs-arm.h b/deps/v8/src/arm/code-stubs-arm.h index e572fd9a1b0ce2..845e38a85ed062 100644 --- a/deps/v8/src/arm/code-stubs-arm.h +++ b/deps/v8/src/arm/code-stubs-arm.h @@ -311,6 +311,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub { DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_CODE_STUBS_ARM_H_ diff --git a/deps/v8/src/arm/codegen-arm.h b/deps/v8/src/arm/codegen-arm.h index d36ce59d66990c..f54fb71d0aefc7 100644 --- a/deps/v8/src/arm/codegen-arm.h +++ b/deps/v8/src/arm/codegen-arm.h @@ -44,6 +44,7 @@ class MathExpGenerator : public AllStatic { DISALLOW_COPY_AND_ASSIGN(MathExpGenerator); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_CODEGEN_ARM_H_ diff --git a/deps/v8/src/arm/constants-arm.cc b/deps/v8/src/arm/constants-arm.cc index 9fefc3140a9994..915d9030e8922a 100644 --- a/deps/v8/src/arm/constants-arm.cc +++ b/deps/v8/src/arm/constants-arm.cc @@ -51,17 +51,6 @@ const Registers::RegisterAlias Registers::aliases_[] = { }; -const char* Registers::Name(int reg) { - const char* result; - if ((0 <= reg) && (reg < kNumRegisters)) { - result = names_[reg]; - } else { - result = "noreg"; - } - return result; -} - - // Support for VFP registers s0 to s31 (d0 to d15) and d16-d31. // Note that "sN:sM" is the same as "dN/2" up to d15. // These register names are defined in a way to match the native disassembler diff --git a/deps/v8/src/arm/constants-arm.h b/deps/v8/src/arm/constants-arm.h index 6d544f3f3684ee..efc060a82ddd4e 100644 --- a/deps/v8/src/arm/constants-arm.h +++ b/deps/v8/src/arm/constants-arm.h @@ -702,6 +702,7 @@ class VFPRegisters { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_CONSTANTS_ARM_H_ diff --git a/deps/v8/src/arm/deoptimizer-arm.cc b/deps/v8/src/arm/deoptimizer-arm.cc index 312bb00df3243b..43f2fb34637ede 100644 --- a/deps/v8/src/arm/deoptimizer-arm.cc +++ b/deps/v8/src/arm/deoptimizer-arm.cc @@ -5,6 +5,7 @@ #include "src/codegen.h" #include "src/deoptimizer.h" #include "src/full-codegen/full-codegen.h" +#include "src/register-configuration.h" #include "src/safepoint-table.h" namespace v8 { @@ -93,7 +94,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { } input_->SetRegister(sp.code(), reinterpret_cast(frame->sp())); input_->SetRegister(fp.code(), reinterpret_cast(frame->fp())); - for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { + for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { input_->SetDoubleRegister(i, 0.0); } @@ -142,8 +143,7 @@ void Deoptimizer::TableEntryGenerator::Generate() { // Everything but pc, lr and ip which will be saved but not restored. RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit(); - const int kDoubleRegsSize = - kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters; + const int kDoubleRegsSize = kDoubleSize * DwVfpRegister::kMaxNumRegisters; // Save all allocatable VFP registers before messing with them. DCHECK(kDoubleRegZero.code() == 14); @@ -152,11 +152,11 @@ void Deoptimizer::TableEntryGenerator::Generate() { // Check CPU flags for number of registers, setting the Z condition flag. __ CheckFor32DRegs(ip); - // Push registers d0-d13, and possibly d16-d31, on the stack. + // Push registers d0-d15, and possibly d16-d31, on the stack. // If d16-d31 are not pushed, decrease the stack pointer instead. __ vstm(db_w, sp, d16, d31, ne); __ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq); - __ vstm(db_w, sp, d0, d13); + __ vstm(db_w, sp, d0, d15); // Push all 16 registers (needed to populate FrameDescription::registers_). // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps @@ -211,9 +211,12 @@ void Deoptimizer::TableEntryGenerator::Generate() { // Copy VFP registers to // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] int double_regs_offset = FrameDescription::double_registers_offset(); - for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) { - int dst_offset = i * kDoubleSize + double_regs_offset; - int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; + const RegisterConfiguration* config = + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); + for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { + int code = config->GetAllocatableDoubleCode(i); + int dst_offset = code * kDoubleSize + double_regs_offset; + int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize; __ vldr(d0, sp, src_offset); __ vstr(d0, r1, dst_offset); } diff --git a/deps/v8/src/arm/disasm-arm.cc b/deps/v8/src/arm/disasm-arm.cc index 0cc24e00af0b8e..9d86579f288ccb 100644 --- a/deps/v8/src/arm/disasm-arm.cc +++ b/deps/v8/src/arm/disasm-arm.cc @@ -1923,7 +1923,7 @@ const char* NameConverter::NameOfConstant(byte* addr) const { const char* NameConverter::NameOfCPURegister(int reg) const { - return v8::internal::Registers::Name(reg); + return v8::internal::Register::from_code(reg).ToString(); } diff --git a/deps/v8/src/arm/frames-arm.h b/deps/v8/src/arm/frames-arm.h index dcba34f0175067..1ea7b1af567413 100644 --- a/deps/v8/src/arm/frames-arm.h +++ b/deps/v8/src/arm/frames-arm.h @@ -128,6 +128,7 @@ class JavaScriptFrameConstants : public AllStatic { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_FRAMES_ARM_H_ diff --git a/deps/v8/src/arm/interface-descriptors-arm.cc b/deps/v8/src/arm/interface-descriptors-arm.cc index aa49843bd05bc2..963b77782ad11a 100644 --- a/deps/v8/src/arm/interface-descriptors-arm.cc +++ b/deps/v8/src/arm/interface-descriptors-arm.cc @@ -80,14 +80,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; } const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; } -void VectorStoreTransitionDescriptor::InitializePlatformSpecific( - CallInterfaceDescriptorData* data) { - Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(), - SlotRegister(), VectorRegister(), MapRegister()}; - data->InitializePlatformSpecific(arraysize(registers), registers); -} - - void FastNewClosureDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = {r2}; @@ -109,6 +101,10 @@ void ToNumberDescriptor::InitializePlatformSpecific( } +// static +const Register ToLengthDescriptor::ReceiverRegister() { return r0; } + + // static const Register ToStringDescriptor::ReceiverRegister() { return r0; } @@ -230,6 +226,13 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific( } +void AllocateInNewSpaceDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + Register registers[] = {r0}; + data->InitializePlatformSpecific(arraysize(registers), registers); +} + + void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { // register state @@ -417,16 +420,39 @@ void MathRoundVariantCallFromOptimizedCodeDescriptor:: } -void PushArgsAndCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { - r0, // argument count (including receiver) + r0, // argument count (not including receiver) r2, // address of first argument r1 // the target callable to be call }; data->InitializePlatformSpecific(arraysize(registers), registers); } + +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + Register registers[] = { + r0, // argument count (not including receiver) + r3, // original constructor + r1, // constructor to call + r2 // address of the first argument + }; + data->InitializePlatformSpecific(arraysize(registers), registers); +} + + +void InterpreterCEntryDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + Register registers[] = { + r0, // argument count (argc) + r2, // address of first argument (argv) + r1 // the runtime function to call + }; + data->InitializePlatformSpecific(arraysize(registers), registers); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/arm/interface-descriptors-arm.h b/deps/v8/src/arm/interface-descriptors-arm.h index 6201adc685192f..a64927924e8800 100644 --- a/deps/v8/src/arm/interface-descriptors-arm.h +++ b/deps/v8/src/arm/interface-descriptors-arm.h @@ -20,7 +20,7 @@ class PlatformInterfaceDescriptor { private: TargetAddressStorageMode storage_mode_; }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_INTERFACE_DESCRIPTORS_ARM_H_ diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 49802ba734d641..456bfd56293ebf 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -11,6 +11,7 @@ #include "src/bootstrapper.h" #include "src/codegen.h" #include "src/debug/debug.h" +#include "src/register-configuration.h" #include "src/runtime/runtime.h" #include "src/arm/macro-assembler-arm.h" @@ -23,8 +24,8 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) generating_stub_(false), has_frame_(false) { if (isolate() != NULL) { - code_object_ = Handle(isolate()->heap()->undefined_value(), - isolate()); + code_object_ = + Handle::New(isolate()->heap()->undefined_value(), isolate()); } } @@ -759,7 +760,9 @@ MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { // Number of d-regs not known at snapshot time. DCHECK(!serializer_enabled()); // General purpose registers are pushed last on the stack. - int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize; + const RegisterConfiguration* config = + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); + int doubles_size = config->num_allocatable_double_registers() * kDoubleSize; int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; return MemOperand(sp, doubles_size + register_offset); } @@ -1474,7 +1477,7 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, int offset = Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; ldr(scratch, FieldMemOperand(scratch, offset)); - ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); + ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kNativeContextOffset)); // Check the context is a native context. if (emit_debug_code()) { @@ -2503,7 +2506,7 @@ void MacroAssembler::GetBuiltinFunction(Register target, // Load the builtins object into target register. ldr(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - ldr(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset)); + ldr(target, FieldMemOperand(target, JSGlobalObject::kNativeContextOffset)); // Load the JavaScript builtin function from the builtins object. ldr(target, ContextOperand(target, native_context_index)); } @@ -2650,7 +2653,7 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) { void MacroAssembler::LoadGlobalProxy(Register dst) { ldr(dst, GlobalObjectOperand()); - ldr(dst, FieldMemOperand(dst, GlobalObject::kGlobalProxyOffset)); + ldr(dst, FieldMemOperand(dst, JSGlobalObject::kGlobalProxyOffset)); } @@ -2663,7 +2666,7 @@ void MacroAssembler::LoadTransitionedArrayMapConditional( // Load the global or builtins object from the current context. ldr(scratch, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); + ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kNativeContextOffset)); // Check that the function's map is the same as the expected cached map. ldr(scratch, @@ -2687,8 +2690,8 @@ void MacroAssembler::LoadGlobalFunction(int index, Register function) { ldr(function, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); // Load the native context from the global or builtins object. - ldr(function, FieldMemOperand(function, - GlobalObject::kNativeContextOffset)); + ldr(function, + FieldMemOperand(function, JSGlobalObject::kNativeContextOffset)); // Load the function from the native context. ldr(function, MemOperand(function, Context::SlotOffset(index))); } @@ -3578,8 +3581,11 @@ Register GetRegisterThatIsNotOneOf(Register reg1, if (reg5.is_valid()) regs |= reg5.bit(); if (reg6.is_valid()) regs |= reg6.bit(); - for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { - Register candidate = Register::FromAllocationIndex(i); + const RegisterConfiguration* config = + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); + for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { + int code = config->GetAllocatableGeneralCode(i); + Register candidate = Register::from_code(code); if (regs & candidate.bit()) continue; return candidate; } diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h index d78bf8f49a540a..8ab676f39b2a91 100644 --- a/deps/v8/src/arm/macro-assembler-arm.h +++ b/deps/v8/src/arm/macro-assembler-arm.h @@ -14,17 +14,18 @@ namespace v8 { namespace internal { // Give alias names to registers for calling conventions. -const Register kReturnRegister0 = {kRegister_r0_Code}; -const Register kReturnRegister1 = {kRegister_r1_Code}; -const Register kJSFunctionRegister = {kRegister_r1_Code}; -const Register kContextRegister = {kRegister_r7_Code}; -const Register kInterpreterAccumulatorRegister = {kRegister_r0_Code}; -const Register kInterpreterRegisterFileRegister = {kRegister_r4_Code}; -const Register kInterpreterBytecodeOffsetRegister = {kRegister_r5_Code}; -const Register kInterpreterBytecodeArrayRegister = {kRegister_r6_Code}; -const Register kInterpreterDispatchTableRegister = {kRegister_r8_Code}; -const Register kRuntimeCallFunctionRegister = {kRegister_r1_Code}; -const Register kRuntimeCallArgCountRegister = {kRegister_r0_Code}; +const Register kReturnRegister0 = {Register::kCode_r0}; +const Register kReturnRegister1 = {Register::kCode_r1}; +const Register kJSFunctionRegister = {Register::kCode_r1}; +const Register kContextRegister = {Register::kCode_r7}; +const Register kInterpreterAccumulatorRegister = {Register::kCode_r0}; +const Register kInterpreterRegisterFileRegister = {Register::kCode_r4}; +const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r5}; +const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r6}; +const Register kInterpreterDispatchTableRegister = {Register::kCode_r8}; +const Register kJavaScriptCallArgCountRegister = {Register::kCode_r0}; +const Register kRuntimeCallFunctionRegister = {Register::kCode_r1}; +const Register kRuntimeCallArgCountRegister = {Register::kCode_r0}; // ---------------------------------------------------------------------------- // Static helper functions @@ -36,9 +37,9 @@ inline MemOperand FieldMemOperand(Register object, int offset) { // Give alias names to registers -const Register cp = { kRegister_r7_Code }; // JavaScript context pointer. -const Register pp = { kRegister_r8_Code }; // Constant pool pointer. -const Register kRootRegister = { kRegister_r10_Code }; // Roots array pointer. +const Register cp = {Register::kCode_r7}; // JavaScript context pointer. +const Register pp = {Register::kCode_r8}; // Constant pool pointer. +const Register kRootRegister = {Register::kCode_r10}; // Roots array pointer. // Flags used for AllocateHeapNumber enum TaggingMode { @@ -1564,6 +1565,7 @@ inline MemOperand GlobalObjectOperand() { #endif -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_ diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc index 5da6204050b926..716e804e3a3798 100644 --- a/deps/v8/src/arm/simulator-arm.cc +++ b/deps/v8/src/arm/simulator-arm.cc @@ -298,7 +298,8 @@ void ArmDebugger::Debug() { if (strcmp(arg1, "all") == 0) { for (int i = 0; i < kNumRegisters; i++) { value = GetRegisterValue(i); - PrintF("%3s: 0x%08x %10d", Registers::Name(i), value, value); + PrintF("%3s: 0x%08x %10d", Register::from_code(i).ToString(), + value, value); if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && (i % 2) == 0) { diff --git a/deps/v8/src/arm/simulator-arm.h b/deps/v8/src/arm/simulator-arm.h index a972a77d411c47..0c6aaf8c24dbc4 100644 --- a/deps/v8/src/arm/simulator-arm.h +++ b/deps/v8/src/arm/simulator-arm.h @@ -55,7 +55,8 @@ class SimulatorStack : public v8::internal::AllStatic { static inline void UnregisterCTryCatch() { } }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #else // !defined(USE_SIMULATOR) // Running with a simulator. @@ -459,7 +460,8 @@ class SimulatorStack : public v8::internal::AllStatic { } }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // !defined(USE_SIMULATOR) #endif // V8_ARM_SIMULATOR_ARM_H_ diff --git a/deps/v8/src/arm64/assembler-arm64-inl.h b/deps/v8/src/arm64/assembler-arm64-inl.h index f02207f5497d53..6de7fb1b2ac4c2 100644 --- a/deps/v8/src/arm64/assembler-arm64-inl.h +++ b/deps/v8/src/arm64/assembler-arm64-inl.h @@ -41,7 +41,7 @@ void RelocInfo::set_target_address(Address target, } -inline unsigned CPURegister::code() const { +inline int CPURegister::code() const { DCHECK(IsValid()); return reg_code; } @@ -54,12 +54,12 @@ inline CPURegister::RegisterType CPURegister::type() const { inline RegList CPURegister::Bit() const { - DCHECK(reg_code < (sizeof(RegList) * kBitsPerByte)); + DCHECK(static_cast(reg_code) < (sizeof(RegList) * kBitsPerByte)); return IsValid() ? 1UL << reg_code : 0; } -inline unsigned CPURegister::SizeInBits() const { +inline int CPURegister::SizeInBits() const { DCHECK(IsValid()); return reg_size; } @@ -1259,6 +1259,7 @@ void Assembler::ClearRecordedAstId() { } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_ASSEMBLER_ARM64_INL_H_ diff --git a/deps/v8/src/arm64/assembler-arm64.cc b/deps/v8/src/arm64/assembler-arm64.cc index 37a2f5a29d006f..d981f635ba0f4b 100644 --- a/deps/v8/src/arm64/assembler-arm64.cc +++ b/deps/v8/src/arm64/assembler-arm64.cc @@ -35,6 +35,7 @@ #include "src/arm64/frames-arm64.h" #include "src/base/bits.h" #include "src/base/cpu.h" +#include "src/register-configuration.h" namespace v8 { namespace internal { @@ -109,17 +110,17 @@ void CPURegList::RemoveCalleeSaved() { } -CPURegList CPURegList::GetCalleeSaved(unsigned size) { +CPURegList CPURegList::GetCalleeSaved(int size) { return CPURegList(CPURegister::kRegister, size, 19, 29); } -CPURegList CPURegList::GetCalleeSavedFP(unsigned size) { +CPURegList CPURegList::GetCalleeSavedFP(int size) { return CPURegList(CPURegister::kFPRegister, size, 8, 15); } -CPURegList CPURegList::GetCallerSaved(unsigned size) { +CPURegList CPURegList::GetCallerSaved(int size) { // Registers x0-x18 and lr (x30) are caller-saved. CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 18); list.Combine(lr); @@ -127,7 +128,7 @@ CPURegList CPURegList::GetCallerSaved(unsigned size) { } -CPURegList CPURegList::GetCallerSavedFP(unsigned size) { +CPURegList CPURegList::GetCallerSavedFP(int size) { // Registers d0-d7 and d16-d31 are caller-saved. CPURegList list = CPURegList(CPURegister::kFPRegister, size, 0, 7); list.Combine(CPURegList(CPURegister::kFPRegister, size, 16, 31)); @@ -192,8 +193,11 @@ bool RelocInfo::IsInConstantPool() { Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3, Register reg4) { CPURegList regs(reg1, reg2, reg3, reg4); - for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { - Register candidate = Register::FromAllocationIndex(i); + const RegisterConfiguration* config = + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); + for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { + int code = config->GetAllocatableDoubleCode(i); + Register candidate = Register::from_code(code); if (regs.IncludesAliasOf(candidate)) continue; return candidate; } @@ -1275,10 +1279,8 @@ void Assembler::rorv(const Register& rd, // Bitfield operations. -void Assembler::bfm(const Register& rd, - const Register& rn, - unsigned immr, - unsigned imms) { +void Assembler::bfm(const Register& rd, const Register& rn, int immr, + int imms) { DCHECK(rd.SizeInBits() == rn.SizeInBits()); Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); Emit(SF(rd) | BFM | N | @@ -1288,10 +1290,8 @@ void Assembler::bfm(const Register& rd, } -void Assembler::sbfm(const Register& rd, - const Register& rn, - unsigned immr, - unsigned imms) { +void Assembler::sbfm(const Register& rd, const Register& rn, int immr, + int imms) { DCHECK(rd.Is64Bits() || rn.Is32Bits()); Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); Emit(SF(rd) | SBFM | N | @@ -1301,10 +1301,8 @@ void Assembler::sbfm(const Register& rd, } -void Assembler::ubfm(const Register& rd, - const Register& rn, - unsigned immr, - unsigned imms) { +void Assembler::ubfm(const Register& rd, const Register& rn, int immr, + int imms) { DCHECK(rd.SizeInBits() == rn.SizeInBits()); Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); Emit(SF(rd) | UBFM | N | @@ -1314,10 +1312,8 @@ void Assembler::ubfm(const Register& rd, } -void Assembler::extr(const Register& rd, - const Register& rn, - const Register& rm, - unsigned lsb) { +void Assembler::extr(const Register& rd, const Register& rn, const Register& rm, + int lsb) { DCHECK(rd.SizeInBits() == rn.SizeInBits()); DCHECK(rd.SizeInBits() == rm.SizeInBits()); Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); diff --git a/deps/v8/src/arm64/assembler-arm64.h b/deps/v8/src/arm64/assembler-arm64.h index f20be8315e2f0b..41060122d8ba52 100644 --- a/deps/v8/src/arm64/assembler-arm64.h +++ b/deps/v8/src/arm64/assembler-arm64.h @@ -12,7 +12,6 @@ #include "src/arm64/instructions-arm64.h" #include "src/assembler.h" -#include "src/compiler.h" #include "src/globals.h" #include "src/utils.h" @@ -23,12 +22,36 @@ namespace internal { // ----------------------------------------------------------------------------- // Registers. -#define REGISTER_CODE_LIST(R) \ -R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ -R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ -R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ -R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) - +// clang-format off +#define GENERAL_REGISTER_CODE_LIST(R) \ + R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ + R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ + R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ + R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) + +#define GENERAL_REGISTERS(R) \ + R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ + R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ + R(x16) R(x17) R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) \ + R(x24) R(x25) R(x26) R(x27) R(x28) R(x29) R(x30) R(x31) + +#define ALLOCATABLE_GENERAL_REGISTERS(R) \ + R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ + R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ + R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x27) + +#define DOUBLE_REGISTERS(R) \ + R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ + R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d15) \ + R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \ + R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31) + +#define ALLOCATABLE_DOUBLE_REGISTERS(R) \ + R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ + R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \ + R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \ + R(d25) R(d26) R(d27) R(d28) +// clang-format on static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte; @@ -40,6 +63,14 @@ struct FPRegister; struct CPURegister { + enum Code { +#define REGISTER_CODE(R) kCode_##R, + GENERAL_REGISTERS(REGISTER_CODE) +#undef REGISTER_CODE + kAfterLast, + kCode_no_reg = -1 + }; + enum RegisterType { // The kInvalid value is used to detect uninitialized static instances, // which are always zero-initialized before any constructors are called. @@ -49,15 +80,15 @@ struct CPURegister { kNoRegister }; - static CPURegister Create(unsigned code, unsigned size, RegisterType type) { + static CPURegister Create(int code, int size, RegisterType type) { CPURegister r = {code, size, type}; return r; } - unsigned code() const; + int code() const; RegisterType type() const; RegList Bit() const; - unsigned SizeInBits() const; + int SizeInBits() const; int SizeInBytes() const; bool Is32Bits() const; bool Is64Bits() const; @@ -86,14 +117,14 @@ struct CPURegister { bool is(const CPURegister& other) const { return Is(other); } bool is_valid() const { return IsValid(); } - unsigned reg_code; - unsigned reg_size; + int reg_code; + int reg_size; RegisterType reg_type; }; struct Register : public CPURegister { - static Register Create(unsigned code, unsigned size) { + static Register Create(int code, int size) { return Register(CPURegister::Create(code, size, CPURegister::kRegister)); } @@ -117,6 +148,8 @@ struct Register : public CPURegister { DCHECK(IsValidOrNone()); } + const char* ToString(); + bool IsAllocatable() const; bool IsValid() const { DCHECK(IsRegister() || IsNone()); return IsValidRegister(); @@ -130,6 +163,7 @@ struct Register : public CPURegister { // A few of them may be unused for now. static const int kNumRegisters = kNumberOfRegisters; + STATIC_ASSERT(kNumRegisters == Code::kAfterLast); static int NumRegisters() { return kNumRegisters; } // We allow crankshaft to use the following registers: @@ -146,70 +180,6 @@ struct Register : public CPURegister { // - "low range" // - "high range" // - "context" - static const unsigned kAllocatableLowRangeBegin = 0; - static const unsigned kAllocatableLowRangeEnd = 15; - static const unsigned kAllocatableHighRangeBegin = 18; - static const unsigned kAllocatableHighRangeEnd = 24; - static const unsigned kAllocatableContext = 27; - - // Gap between low and high ranges. - static const int kAllocatableRangeGapSize = - (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; - - static const int kMaxNumAllocatableRegisters = - (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + - (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1) + 1; // cp - static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } - - // Return true if the register is one that crankshaft can allocate. - bool IsAllocatable() const { - return ((reg_code == kAllocatableContext) || - (reg_code <= kAllocatableLowRangeEnd) || - ((reg_code >= kAllocatableHighRangeBegin) && - (reg_code <= kAllocatableHighRangeEnd))); - } - - static Register FromAllocationIndex(unsigned index) { - DCHECK(index < static_cast(NumAllocatableRegisters())); - // cp is the last allocatable register. - if (index == (static_cast(NumAllocatableRegisters() - 1))) { - return from_code(kAllocatableContext); - } - - // Handle low and high ranges. - return (index <= kAllocatableLowRangeEnd) - ? from_code(index) - : from_code(index + kAllocatableRangeGapSize); - } - - static const char* AllocationIndexToString(int index) { - DCHECK((index >= 0) && (index < NumAllocatableRegisters())); - DCHECK((kAllocatableLowRangeBegin == 0) && - (kAllocatableLowRangeEnd == 15) && - (kAllocatableHighRangeBegin == 18) && - (kAllocatableHighRangeEnd == 24) && - (kAllocatableContext == 27)); - const char* const names[] = { - "x0", "x1", "x2", "x3", "x4", - "x5", "x6", "x7", "x8", "x9", - "x10", "x11", "x12", "x13", "x14", - "x15", "x18", "x19", "x20", "x21", - "x22", "x23", "x24", "x27", - }; - return names[index]; - } - - static int ToAllocationIndex(Register reg) { - DCHECK(reg.IsAllocatable()); - unsigned code = reg.code(); - if (code == kAllocatableContext) { - return NumAllocatableRegisters() - 1; - } - - return (code <= kAllocatableLowRangeEnd) - ? code - : code - kAllocatableRangeGapSize; - } static Register from_code(int code) { // Always return an X register. @@ -221,7 +191,15 @@ struct Register : public CPURegister { struct FPRegister : public CPURegister { - static FPRegister Create(unsigned code, unsigned size) { + enum Code { +#define REGISTER_CODE(R) kCode_##R, + DOUBLE_REGISTERS(REGISTER_CODE) +#undef REGISTER_CODE + kAfterLast, + kCode_no_reg = -1 + }; + + static FPRegister Create(int code, int size) { return FPRegister( CPURegister::Create(code, size, CPURegister::kFPRegister)); } @@ -246,6 +224,8 @@ struct FPRegister : public CPURegister { DCHECK(IsValidOrNone()); } + const char* ToString(); + bool IsAllocatable() const; bool IsValid() const { DCHECK(IsFPRegister() || IsNone()); return IsValidFPRegister(); @@ -256,69 +236,12 @@ struct FPRegister : public CPURegister { // Start of V8 compatibility section --------------------- static const int kMaxNumRegisters = kNumberOfFPRegisters; + STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast); // Crankshaft can use all the FP registers except: // - d15 which is used to keep the 0 double value // - d30 which is used in crankshaft as a double scratch register // - d31 which is used in the MacroAssembler as a double scratch register - static const unsigned kAllocatableLowRangeBegin = 0; - static const unsigned kAllocatableLowRangeEnd = 14; - static const unsigned kAllocatableHighRangeBegin = 16; - static const unsigned kAllocatableHighRangeEnd = 28; - - static const RegList kAllocatableFPRegisters = 0x1fff7fff; - - // Gap between low and high ranges. - static const int kAllocatableRangeGapSize = - (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; - - static const int kMaxNumAllocatableRegisters = - (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + - (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1); - static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } - - // TODO(turbofan): Proper float32 support. - static int NumAllocatableAliasedRegisters() { - return NumAllocatableRegisters(); - } - - // Return true if the register is one that crankshaft can allocate. - bool IsAllocatable() const { - return (Bit() & kAllocatableFPRegisters) != 0; - } - - static FPRegister FromAllocationIndex(unsigned int index) { - DCHECK(index < static_cast(NumAllocatableRegisters())); - - return (index <= kAllocatableLowRangeEnd) - ? from_code(index) - : from_code(index + kAllocatableRangeGapSize); - } - - static const char* AllocationIndexToString(int index) { - DCHECK((index >= 0) && (index < NumAllocatableRegisters())); - DCHECK((kAllocatableLowRangeBegin == 0) && - (kAllocatableLowRangeEnd == 14) && - (kAllocatableHighRangeBegin == 16) && - (kAllocatableHighRangeEnd == 28)); - const char* const names[] = { - "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", - "d8", "d9", "d10", "d11", "d12", "d13", "d14", - "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", - "d24", "d25", "d26", "d27", "d28" - }; - return names[index]; - } - - static int ToAllocationIndex(FPRegister reg) { - DCHECK(reg.IsAllocatable()); - unsigned code = reg.code(); - - return (code <= kAllocatableLowRangeEnd) - ? code - : code - kAllocatableRangeGapSize; - } - static FPRegister from_code(int code) { // Always return a D register. return FPRegister::Create(code, kDRegSizeInBits); @@ -361,7 +284,7 @@ INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister); kWRegSizeInBits, CPURegister::kRegister); \ INITIALIZE_REGISTER(Register, x##N, N, \ kXRegSizeInBits, CPURegister::kRegister); -REGISTER_CODE_LIST(DEFINE_REGISTERS) +GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) #undef DEFINE_REGISTERS INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits, @@ -374,7 +297,7 @@ INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits, kSRegSizeInBits, CPURegister::kFPRegister); \ INITIALIZE_REGISTER(FPRegister, d##N, N, \ kDRegSizeInBits, CPURegister::kFPRegister); -REGISTER_CODE_LIST(DEFINE_FPREGISTERS) +GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS) #undef DEFINE_FPREGISTERS #undef INITIALIZE_REGISTER @@ -461,13 +384,13 @@ class CPURegList { DCHECK(IsValid()); } - CPURegList(CPURegister::RegisterType type, unsigned size, RegList list) + CPURegList(CPURegister::RegisterType type, int size, RegList list) : list_(list), size_(size), type_(type) { DCHECK(IsValid()); } - CPURegList(CPURegister::RegisterType type, unsigned size, - unsigned first_reg, unsigned last_reg) + CPURegList(CPURegister::RegisterType type, int size, int first_reg, + int last_reg) : size_(size), type_(type) { DCHECK(((type == CPURegister::kRegister) && (last_reg < kNumberOfRegisters)) || @@ -524,12 +447,12 @@ class CPURegList { CPURegister PopHighestIndex(); // AAPCS64 callee-saved registers. - static CPURegList GetCalleeSaved(unsigned size = kXRegSizeInBits); - static CPURegList GetCalleeSavedFP(unsigned size = kDRegSizeInBits); + static CPURegList GetCalleeSaved(int size = kXRegSizeInBits); + static CPURegList GetCalleeSavedFP(int size = kDRegSizeInBits); // AAPCS64 caller-saved registers. Note that this includes lr. - static CPURegList GetCallerSaved(unsigned size = kXRegSizeInBits); - static CPURegList GetCallerSavedFP(unsigned size = kDRegSizeInBits); + static CPURegList GetCallerSaved(int size = kXRegSizeInBits); + static CPURegList GetCallerSavedFP(int size = kDRegSizeInBits); // Registers saved as safepoints. static CPURegList GetSafepointSavedRegisters(); @@ -557,25 +480,25 @@ class CPURegList { return CountSetBits(list_, kRegListSizeInBits); } - unsigned RegisterSizeInBits() const { + int RegisterSizeInBits() const { DCHECK(IsValid()); return size_; } - unsigned RegisterSizeInBytes() const { + int RegisterSizeInBytes() const { int size_in_bits = RegisterSizeInBits(); DCHECK((size_in_bits % kBitsPerByte) == 0); return size_in_bits / kBitsPerByte; } - unsigned TotalSizeInBytes() const { + int TotalSizeInBytes() const { DCHECK(IsValid()); return RegisterSizeInBytes() * Count(); } private: RegList list_; - unsigned size_; + int size_; CPURegister::RegisterType type_; bool IsValid() const { @@ -1197,39 +1120,24 @@ class Assembler : public AssemblerBase { // Bitfield instructions. // Bitfield move. - void bfm(const Register& rd, - const Register& rn, - unsigned immr, - unsigned imms); + void bfm(const Register& rd, const Register& rn, int immr, int imms); // Signed bitfield move. - void sbfm(const Register& rd, - const Register& rn, - unsigned immr, - unsigned imms); + void sbfm(const Register& rd, const Register& rn, int immr, int imms); // Unsigned bitfield move. - void ubfm(const Register& rd, - const Register& rn, - unsigned immr, - unsigned imms); + void ubfm(const Register& rd, const Register& rn, int immr, int imms); // Bfm aliases. // Bitfield insert. - void bfi(const Register& rd, - const Register& rn, - unsigned lsb, - unsigned width) { + void bfi(const Register& rd, const Register& rn, int lsb, int width) { DCHECK(width >= 1); DCHECK(lsb + width <= rn.SizeInBits()); bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); } // Bitfield extract and insert low. - void bfxil(const Register& rd, - const Register& rn, - unsigned lsb, - unsigned width) { + void bfxil(const Register& rd, const Register& rn, int lsb, int width) { DCHECK(width >= 1); DCHECK(lsb + width <= rn.SizeInBits()); bfm(rd, rn, lsb, lsb + width - 1); @@ -1237,26 +1145,20 @@ class Assembler : public AssemblerBase { // Sbfm aliases. // Arithmetic shift right. - void asr(const Register& rd, const Register& rn, unsigned shift) { + void asr(const Register& rd, const Register& rn, int shift) { DCHECK(shift < rd.SizeInBits()); sbfm(rd, rn, shift, rd.SizeInBits() - 1); } // Signed bitfield insert in zero. - void sbfiz(const Register& rd, - const Register& rn, - unsigned lsb, - unsigned width) { + void sbfiz(const Register& rd, const Register& rn, int lsb, int width) { DCHECK(width >= 1); DCHECK(lsb + width <= rn.SizeInBits()); sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); } // Signed bitfield extract. - void sbfx(const Register& rd, - const Register& rn, - unsigned lsb, - unsigned width) { + void sbfx(const Register& rd, const Register& rn, int lsb, int width) { DCHECK(width >= 1); DCHECK(lsb + width <= rn.SizeInBits()); sbfm(rd, rn, lsb, lsb + width - 1); @@ -1279,33 +1181,27 @@ class Assembler : public AssemblerBase { // Ubfm aliases. // Logical shift left. - void lsl(const Register& rd, const Register& rn, unsigned shift) { - unsigned reg_size = rd.SizeInBits(); + void lsl(const Register& rd, const Register& rn, int shift) { + int reg_size = rd.SizeInBits(); DCHECK(shift < reg_size); ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1); } // Logical shift right. - void lsr(const Register& rd, const Register& rn, unsigned shift) { + void lsr(const Register& rd, const Register& rn, int shift) { DCHECK(shift < rd.SizeInBits()); ubfm(rd, rn, shift, rd.SizeInBits() - 1); } // Unsigned bitfield insert in zero. - void ubfiz(const Register& rd, - const Register& rn, - unsigned lsb, - unsigned width) { + void ubfiz(const Register& rd, const Register& rn, int lsb, int width) { DCHECK(width >= 1); DCHECK(lsb + width <= rn.SizeInBits()); ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); } // Unsigned bitfield extract. - void ubfx(const Register& rd, - const Register& rn, - unsigned lsb, - unsigned width) { + void ubfx(const Register& rd, const Register& rn, int lsb, int width) { DCHECK(width >= 1); DCHECK(lsb + width <= rn.SizeInBits()); ubfm(rd, rn, lsb, lsb + width - 1); @@ -1327,10 +1223,8 @@ class Assembler : public AssemblerBase { } // Extract. - void extr(const Register& rd, - const Register& rn, - const Register& rm, - unsigned lsb); + void extr(const Register& rd, const Register& rn, const Register& rm, + int lsb); // Conditional select: rd = cond ? rn : rm. void csel(const Register& rd, @@ -2296,6 +2190,7 @@ class EnsureSpace BASE_EMBEDDED { } }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ diff --git a/deps/v8/src/arm64/builtins-arm64.cc b/deps/v8/src/arm64/builtins-arm64.cc index 433119801761b4..f7ea89d8074f8d 100644 --- a/deps/v8/src/arm64/builtins-arm64.cc +++ b/deps/v8/src/arm64/builtins-arm64.cc @@ -22,8 +22,7 @@ namespace internal { static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { // Load the native context. __ Ldr(result, GlobalObjectMemOperand()); - __ Ldr(result, - FieldMemOperand(result, GlobalObject::kNativeContextOffset)); + __ Ldr(result, FieldMemOperand(result, JSGlobalObject::kNativeContextOffset)); // Load the InternalArray function from the native context. __ Ldr(result, MemOperand(result, @@ -36,8 +35,7 @@ static void GenerateLoadInternalArrayFunction(MacroAssembler* masm, Register result) { // Load the native context. __ Ldr(result, GlobalObjectMemOperand()); - __ Ldr(result, - FieldMemOperand(result, GlobalObject::kNativeContextOffset)); + __ Ldr(result, FieldMemOperand(result, JSGlobalObject::kNativeContextOffset)); // Load the InternalArray function from the native context. __ Ldr(result, ContextMemOperand(result, Context::INTERNAL_ARRAY_FUNCTION_INDEX)); @@ -49,11 +47,12 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- x0 : number of arguments excluding receiver - // -- x1 : called function (only guaranteed when - // extra_args requires it) + // (only guaranteed when the called function + // is not marked as DontAdaptArguments) + // -- x1 : called function // -- sp[0] : last argument // -- ... - // -- sp[4 * (argc - 1)] : first argument (argc == x0) + // -- sp[4 * (argc - 1)] : first argument // -- sp[4 * argc] : receiver // ----------------------------------- __ AssertFunction(x1); @@ -75,8 +74,16 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, } // JumpToExternalReference expects x0 to contain the number of arguments - // including the receiver and the extra arguments. + // including the receiver and the extra arguments. But x0 is only valid + // if the called function is marked as DontAdaptArguments, otherwise we + // need to load the argument count from the SharedFunctionInfo. + __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); + __ Ldrsw( + x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); + __ Cmp(x2, SharedFunctionInfo::kDontAdaptArgumentsSentinel); + __ Csel(x0, x0, x2, eq); __ Add(x0, x0, num_extra_args + 1); + __ JumpToExternalReference(ExternalReference(id, masm->isolate())); } @@ -200,6 +207,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- x0 : number of arguments // -- x1 : constructor function + // -- x3 : original constructor // -- lr : return address // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) // -- sp[argc * 8] : receiver @@ -225,16 +233,16 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { { Label convert, done_convert; __ JumpIfSmi(x2, &convert); - __ JumpIfObjectType(x2, x3, x3, FIRST_NONSTRING_TYPE, &done_convert, lo); + __ JumpIfObjectType(x2, x4, x4, FIRST_NONSTRING_TYPE, &done_convert, lo); __ Bind(&convert); { FrameScope scope(masm, StackFrame::INTERNAL); ToStringStub stub(masm->isolate()); - __ Push(x1); + __ Push(x1, x3); __ Move(x0, x2); __ CallStub(&stub); __ Move(x2, x0); - __ Pop(x1); + __ Pop(x1, x3); } __ Bind(&done_convert); } @@ -242,12 +250,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { // 3. Allocate a JSValue wrapper for the string. { // ----------- S t a t e ------------- - // -- x1 : constructor function // -- x2 : the first argument + // -- x1 : constructor function + // -- x3 : original constructor // -- lr : return address // ----------------------------------- - Label allocate, done_allocate; + Label allocate, done_allocate, rt_call; + + // Fall back to runtime if the original constructor and function differ. + __ cmp(x1, x3); + __ B(ne, &rt_call); + __ Allocate(JSValue::kSize, x0, x3, x4, &allocate, TAG_OBJECT); __ Bind(&done_allocate); @@ -271,6 +285,17 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { __ Pop(x2, x1); } __ B(&done_allocate); + + // Fallback to the runtime to create new object. + __ bind(&rt_call); + { + FrameScope scope(masm, StackFrame::INTERNAL); + __ Push(x1, x2, x1, x3); // constructor function, original constructor + __ CallRuntime(Runtime::kNewObject, 2); + __ Pop(x2, x1); + } + __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); + __ Ret(); } } @@ -327,7 +352,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // -- x0 : number of arguments // -- x1 : constructor function // -- x2 : allocation site or undefined - // -- x3 : original constructor + // -- x3 : original constructor // -- lr : return address // -- sp[...]: constructor arguments // ----------------------------------- @@ -365,18 +390,25 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ Ldr(x2, MemOperand(x2)); __ Cbnz(x2, &rt_call); - // Fall back to runtime if the original constructor and function differ. - __ Cmp(constructor, original_constructor); - __ B(ne, &rt_call); + // Verify that the original constructor is a JSFunction. + __ JumpIfNotObjectType(original_constructor, x10, x11, JS_FUNCTION_TYPE, + &rt_call); // Load the initial map and verify that it is in fact a map. Register init_map = x2; __ Ldr(init_map, - FieldMemOperand(constructor, + FieldMemOperand(original_constructor, JSFunction::kPrototypeOrInitialMapOffset)); __ JumpIfSmi(init_map, &rt_call); __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call); + // Fall back to runtime if the expected base constructor and base + // constructor differ. + __ Ldr(x10, + FieldMemOperand(init_map, Map::kConstructorOrBackPointerOffset)); + __ Cmp(constructor, x10); + __ B(ne, &rt_call); + // Check that the constructor is not constructing a JSFunction (see // comments in Runtime_NewObject in runtime.cc). In which case the initial // map's instance type would be JS_FUNCTION_TYPE. @@ -399,9 +431,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); __ B(ne, &allocate); - // Push the constructor and map to the stack, and the constructor again + // Push the constructor and map to the stack, and the map again // as argument to the runtime call. - __ Push(constructor, init_map, constructor); + __ Push(constructor, init_map, init_map); __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); __ Pop(init_map, constructor); __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); @@ -699,7 +731,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { ParameterCount actual(x0); __ InvokeFunction(x1, actual, CALL_FUNCTION, NullCallWrapper()); - // Restore the context from the frame. // x0: result // jssp[0]: number of arguments (smi-tagged) @@ -924,28 +955,16 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // - Support profiler (specifically profiling_counter). // - Call ProfileEntryHookStub when isolate has a function_entry_hook. // - Allow simulator stop operations if FLAG_stop_at is set. - // - Deal with sloppy mode functions which need to replace the - // receiver with the global proxy when called as functions (without an - // explicit receiver object). // - Code aging of the BytecodeArray object. - // - Supporting FLAG_trace. - // - // The following items are also not done here, and will probably be done using - // explicit bytecodes instead: - // - Allocating a new local context if applicable. - // - Setting up a local binding to the this function, which is used in - // derived constructors with super calls. - // - Setting new.target if required. - // - Dealing with REST parameters (only if - // https://codereview.chromium.org/1235153006 doesn't land by then). - // - Dealing with argument objects. // Perform stack guard check. { Label ok; __ CompareRoot(jssp, Heap::kStackLimitRootIndex); __ B(hs, &ok); + __ Push(kInterpreterBytecodeArrayRegister); __ CallRuntime(Runtime::kStackGuard, 0); + __ Pop(kInterpreterBytecodeArrayRegister); __ Bind(&ok); } @@ -1542,69 +1561,83 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { // static -void Builtins::Generate_CallFunction(MacroAssembler* masm) { +void Builtins::Generate_CallFunction(MacroAssembler* masm, + ConvertReceiverMode mode) { // ----------- S t a t e ------------- // -- x0 : the number of arguments (not including the receiver) // -- x1 : the function to call (checked to be a JSFunction) // ----------------------------------- - - Label convert, convert_global_proxy, convert_to_object, done_convert; __ AssertFunction(x1); - // TODO(bmeurer): Throw a TypeError if function's [[FunctionKind]] internal - // slot is "classConstructor". + + // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) + // Check that function is not a "classConstructor". + Label class_constructor; + __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); + __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); + __ TestAndBranchIfAnySet( + w3, (1 << SharedFunctionInfo::kIsDefaultConstructor) | + (1 << SharedFunctionInfo::kIsSubclassConstructor) | + (1 << SharedFunctionInfo::kIsBaseConstructor), + &class_constructor); + // Enter the context of the function; ToObject has to run in the function // context, and we also need to take the global proxy from the function // context in case of conversion. - // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); - __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); // We need to convert the receiver for non-native sloppy mode functions. - __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); + Label done_convert; __ TestAndBranchIfAnySet(w3, (1 << SharedFunctionInfo::kNative) | (1 << SharedFunctionInfo::kStrictModeFunction), &done_convert); { - __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2)); - // ----------- S t a t e ------------- // -- x0 : the number of arguments (not including the receiver) // -- x1 : the function to call (checked to be a JSFunction) // -- x2 : the shared function info. - // -- x3 : the receiver // -- cp : the function context. // ----------------------------------- - Label convert_receiver; - __ JumpIfSmi(x3, &convert_to_object); - STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); - __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE); - __ B(hs, &done_convert); - __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &convert_global_proxy); - __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object); - __ Bind(&convert_global_proxy); - { + if (mode == ConvertReceiverMode::kNullOrUndefined) { // Patch receiver to global proxy. __ LoadGlobalProxy(x3); + } else { + Label convert_to_object, convert_receiver; + __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2)); + __ JumpIfSmi(x3, &convert_to_object); + STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); + __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE); + __ B(hs, &done_convert); + if (mode != ConvertReceiverMode::kNotNullOrUndefined) { + Label convert_global_proxy; + __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, + &convert_global_proxy); + __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object); + __ Bind(&convert_global_proxy); + { + // Patch receiver to global proxy. + __ LoadGlobalProxy(x3); + } + __ B(&convert_receiver); + } + __ Bind(&convert_to_object); + { + // Convert receiver using ToObject. + // TODO(bmeurer): Inline the allocation here to avoid building the frame + // in the fast case? (fall back to AllocateInNewSpace?) + FrameScope scope(masm, StackFrame::INTERNAL); + __ SmiTag(x0); + __ Push(x0, x1); + __ Mov(x0, x3); + ToObjectStub stub(masm->isolate()); + __ CallStub(&stub); + __ Mov(x3, x0); + __ Pop(x1, x0); + __ SmiUntag(x0); + } + __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); + __ Bind(&convert_receiver); } - __ B(&convert_receiver); - __ Bind(&convert_to_object); - { - // Convert receiver using ToObject. - // TODO(bmeurer): Inline the allocation here to avoid building the frame - // in the fast case? (fall back to AllocateInNewSpace?) - FrameScope scope(masm, StackFrame::INTERNAL); - __ SmiTag(x0); - __ Push(x0, x1); - __ Mov(x0, x3); - ToObjectStub stub(masm->isolate()); - __ CallStub(&stub); - __ Mov(x3, x0); - __ Pop(x1, x0); - __ SmiUntag(x0); - } - __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); - __ Bind(&convert_receiver); __ Poke(x3, Operand(x0, LSL, kXRegSizeLog2)); } __ Bind(&done_convert); @@ -1622,11 +1655,18 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm) { ParameterCount actual(x0); ParameterCount expected(x2); __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); + + // The function is a "classConstructor", need to raise an exception. + __ bind(&class_constructor); + { + FrameScope frame(masm, StackFrame::INTERNAL); + __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); + } } // static -void Builtins::Generate_Call(MacroAssembler* masm) { +void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // ----------- S t a t e ------------- // -- x0 : the number of arguments (not including the receiver) // -- x1 : the target to call (can be any Object). @@ -1636,8 +1676,8 @@ void Builtins::Generate_Call(MacroAssembler* masm) { __ JumpIfSmi(x1, &non_callable); __ Bind(&non_smi); __ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE); - __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, - eq); + __ Jump(masm->isolate()->builtins()->CallFunction(mode), + RelocInfo::CODE_TARGET, eq); __ Cmp(x5, JS_FUNCTION_PROXY_TYPE); __ B(ne, &non_function); @@ -1657,7 +1697,9 @@ void Builtins::Generate_Call(MacroAssembler* masm) { __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2)); // Let the "call_as_function_delegate" take care of the rest. __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, x1); - __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); + __ Jump(masm->isolate()->builtins()->CallFunction( + ConvertReceiverMode::kNotNullOrUndefined), + RelocInfo::CODE_TARGET); // 3. Call to something that is not callable. __ bind(&non_callable); @@ -1753,13 +1795,14 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { // static -void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { +void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- x0 : the number of arguments (not including the receiver) // -- x2 : the address of the first argument to be pushed. Subsequent // arguments should be consecutive above this, in the same order as // they are to be pushed onto the stack. // -- x1 : the target to call (can be any Object). + // ----------------------------------- // Find the address of the last argument. __ add(x3, x0, Operand(1)); // Add one for receiver. @@ -1784,6 +1827,43 @@ void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { } +// static +void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { + // ----------- S t a t e ------------- + // -- x0 : argument count (not including receiver) + // -- x3 : original constructor + // -- x1 : constructor to call + // -- x2 : address of the first argument + // ----------------------------------- + + // Find the address of the last argument. + __ add(x5, x0, Operand(1)); // Add one for receiver (to be constructed). + __ lsl(x5, x5, kPointerSizeLog2); + + // Set stack pointer and where to stop. + __ Mov(x6, jssp); + __ Claim(x5, 1); + __ sub(x4, x6, x5); + + // Push a slot for the receiver. + __ Str(xzr, MemOperand(x6, -kPointerSize, PreIndex)); + + Label loop_header, loop_check; + // Push the arguments. + __ B(&loop_check); + __ Bind(&loop_header); + // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned. + __ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex)); + __ Str(x5, MemOperand(x6, -kPointerSize, PreIndex)); + __ Bind(&loop_check); + __ Cmp(x6, x4); + __ B(gt, &loop_header); + + // Call the constructor with x0, x1, and x3 unmodified. + __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL); +} + + void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); // ----------- S t a t e ------------- diff --git a/deps/v8/src/arm64/code-stubs-arm64.cc b/deps/v8/src/arm64/code-stubs-arm64.cc index e39e08831a077f..751d8aebde99f4 100644 --- a/deps/v8/src/arm64/code-stubs-arm64.cc +++ b/deps/v8/src/arm64/code-stubs-arm64.cc @@ -1067,6 +1067,8 @@ void CEntryStub::Generate(MacroAssembler* masm) { // Register parameters: // x0: argc (including receiver, untagged) // x1: target + // If argv_in_register(): + // x11: argv (pointer to first argument) // // The stack on entry holds the arguments and the receiver, with the receiver // at the highest address: @@ -1098,9 +1100,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { // (arg[argc-2]), or just below the receiver in case there are no arguments. // - Adjust for the arg[] array. Register temp_argv = x11; - __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2)); - // - Adjust for the receiver. - __ Sub(temp_argv, temp_argv, 1 * kPointerSize); + if (!argv_in_register()) { + __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2)); + // - Adjust for the receiver. + __ Sub(temp_argv, temp_argv, 1 * kPointerSize); + } // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved // registers. @@ -1204,12 +1208,10 @@ void CEntryStub::Generate(MacroAssembler* masm) { __ LeaveExitFrame(save_doubles(), x10, true); DCHECK(jssp.Is(__ StackPointer())); - // Pop or drop the remaining stack slots and return from the stub. - // jssp[24]: Arguments array (of size argc), including receiver. - // jssp[16]: Preserved x23 (used for target). - // jssp[8]: Preserved x22 (used for argc). - // jssp[0]: Preserved x21 (used for argv). - __ Drop(x11); + if (!argv_in_register()) { + // Drop the remaining stack slots and return from the stub. + __ Drop(x11); + } __ AssertFPCRState(); __ Ret(); @@ -1804,8 +1806,8 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { Register sloppy_args_map = x11; Register aliased_args_map = x10; __ Ldr(global_object, GlobalObjectMemOperand()); - __ Ldr(global_ctx, FieldMemOperand(global_object, - GlobalObject::kNativeContextOffset)); + __ Ldr(global_ctx, + FieldMemOperand(global_object, JSGlobalObject::kNativeContextOffset)); __ Ldr(sloppy_args_map, ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); @@ -2049,8 +2051,8 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { Register global_ctx = x10; Register strict_args_map = x4; __ Ldr(global_object, GlobalObjectMemOperand()); - __ Ldr(global_ctx, FieldMemOperand(global_object, - GlobalObject::kNativeContextOffset)); + __ Ldr(global_ctx, + FieldMemOperand(global_object, JSGlobalObject::kNativeContextOffset)); __ Ldr(strict_args_map, ContextMemOperand(global_ctx, Context::STRICT_ARGUMENTS_MAP_INDEX)); @@ -2745,101 +2747,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc, } -static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { - // Do not transform the receiver for strict mode functions. - __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); - __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset)); - __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont); - - // Do not transform the receiver for native (Compilerhints already in x3). - __ Tbnz(w4, SharedFunctionInfo::kNative, cont); -} - - -static void EmitSlowCase(MacroAssembler* masm, int argc) { - __ Mov(x0, argc); - __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); -} - - -static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { - // Wrap the receiver and patch it back onto the stack. - { FrameScope frame_scope(masm, StackFrame::INTERNAL); - __ Push(x1); - __ Mov(x0, x3); - ToObjectStub stub(masm->isolate()); - __ CallStub(&stub); - __ Pop(x1); - } - __ Poke(x0, argc * kPointerSize); - __ B(cont); -} - - -static void CallFunctionNoFeedback(MacroAssembler* masm, - int argc, bool needs_checks, - bool call_as_method) { - // x1 function the function to call - Register function = x1; - Register type = x4; - Label slow, wrap, cont; - - // TODO(jbramley): This function has a lot of unnamed registers. Name them, - // and tidy things up a bit. - - if (needs_checks) { - // Check that the function is really a JavaScript function. - __ JumpIfSmi(function, &slow); - - // Goto slow case if we do not have a function. - __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); - } - - // Fast-case: Invoke the function now. - // x1 function pushed function - ParameterCount actual(argc); - - if (call_as_method) { - if (needs_checks) { - EmitContinueIfStrictOrNative(masm, &cont); - } - - // Compute the receiver in sloppy mode. - __ Peek(x3, argc * kPointerSize); - - if (needs_checks) { - __ JumpIfSmi(x3, &wrap); - __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt); - } else { - __ B(&wrap); - } - - __ Bind(&cont); - } - - __ InvokeFunction(function, - actual, - JUMP_FUNCTION, - NullCallWrapper()); - if (needs_checks) { - // Slow-case: Non-function called. - __ Bind(&slow); - EmitSlowCase(masm, argc); - } - - if (call_as_method) { - __ Bind(&wrap); - EmitWrapCase(masm, argc, &cont); - } -} - - -void CallFunctionStub::Generate(MacroAssembler* masm) { - ASM_LOCATION("CallFunctionStub::Generate"); - CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); -} - - void CallConstructStub::Generate(MacroAssembler* masm) { ASM_LOCATION("CallConstructStub::Generate"); // x0 : number of arguments @@ -2939,16 +2846,13 @@ void CallICStub::Generate(MacroAssembler* masm) { FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); const int generic_offset = FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); - Label extra_checks_or_miss, slow_start; - Label slow, wrap, cont; - Label have_js_function; + Label extra_checks_or_miss, call; int argc = arg_count(); ParameterCount actual(argc); Register function = x1; Register feedback_vector = x2; Register index = x3; - Register type = x4; // The checks. First, does x1 match the recorded monomorphic target? __ Add(x4, feedback_vector, @@ -2986,36 +2890,14 @@ void CallICStub::Generate(MacroAssembler* masm) { __ Add(index, index, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); __ Str(index, FieldMemOperand(feedback_vector, 0)); - __ bind(&have_js_function); - if (CallAsMethod()) { - EmitContinueIfStrictOrNative(masm, &cont); - - // Compute the receiver in sloppy mode. - __ Peek(x3, argc * kPointerSize); - - __ JumpIfSmi(x3, &wrap); - __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt); - - __ Bind(&cont); - } - - __ InvokeFunction(function, - actual, - JUMP_FUNCTION, - NullCallWrapper()); - - __ bind(&slow); - EmitSlowCase(masm, argc); - - if (CallAsMethod()) { - __ bind(&wrap); - EmitWrapCase(masm, argc, &cont); - } + __ bind(&call); + __ Mov(x0, argc); + __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); __ bind(&extra_checks_or_miss); Label uninitialized, miss, not_allocation_site; - __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &slow_start); + __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &call); __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset)); __ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, ¬_allocation_site); @@ -3047,7 +2929,7 @@ void CallICStub::Generate(MacroAssembler* masm) { __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset)); __ Adds(x4, x4, Operand(Smi::FromInt(1))); __ Str(x4, FieldMemOperand(feedback_vector, generic_offset)); - __ B(&slow_start); + __ B(&call); __ bind(&uninitialized); @@ -3086,22 +2968,14 @@ void CallICStub::Generate(MacroAssembler* masm) { __ Pop(function); } - __ B(&have_js_function); + __ B(&call); // We are here because tracing is on or we encountered a MISS case we can't // handle here. __ bind(&miss); GenerateMiss(masm); - // the slow case - __ bind(&slow_start); - - // Check that the function is really a JavaScript function. - __ JumpIfSmi(function, &slow); - - // Goto slow case if we do not have a function. - __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); - __ B(&have_js_function); + __ B(&call); } @@ -3235,7 +3109,7 @@ void StringCharFromCodeGenerator::GenerateSlow( __ Bind(&slow_case_); call_helper.BeforeCall(masm); __ Push(code_); - __ CallRuntime(Runtime::kCharFromCode, 1); + __ CallRuntime(Runtime::kStringCharFromCode, 1); __ Mov(result_, x0); call_helper.AfterCall(masm); __ B(&exit_); @@ -3912,6 +3786,21 @@ void ToNumberStub::Generate(MacroAssembler* masm) { } +void ToLengthStub::Generate(MacroAssembler* masm) { + // The ToLength stub takes one argument in x0. + Label not_smi; + __ JumpIfNotSmi(x0, ¬_smi); + STATIC_ASSERT(kSmiTag == 0); + __ Tst(x0, x0); + __ Csel(x0, x0, Operand(0), ge); + __ Ret(); + __ Bind(¬_smi); + + __ Push(x0); // Push argument. + __ TailCallRuntime(Runtime::kToLength, 1, 1); +} + + void ToStringStub::Generate(MacroAssembler* masm) { // The ToString stub takes one argument in x0. Label is_number; diff --git a/deps/v8/src/arm64/code-stubs-arm64.h b/deps/v8/src/arm64/code-stubs-arm64.h index 1b64a625f99f73..341153380dcd6b 100644 --- a/deps/v8/src/arm64/code-stubs-arm64.h +++ b/deps/v8/src/arm64/code-stubs-arm64.h @@ -384,6 +384,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub { DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_CODE_STUBS_ARM64_H_ diff --git a/deps/v8/src/arm64/codegen-arm64.h b/deps/v8/src/arm64/codegen-arm64.h index 2f01c510de7fee..7100ef1134d2f9 100644 --- a/deps/v8/src/arm64/codegen-arm64.h +++ b/deps/v8/src/arm64/codegen-arm64.h @@ -43,6 +43,7 @@ class MathExpGenerator : public AllStatic { DISALLOW_COPY_AND_ASSIGN(MathExpGenerator); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_CODEGEN_ARM64_H_ diff --git a/deps/v8/src/arm64/constants-arm64.h b/deps/v8/src/arm64/constants-arm64.h index 1529c647ff75c8..43a375d953d6d9 100644 --- a/deps/v8/src/arm64/constants-arm64.h +++ b/deps/v8/src/arm64/constants-arm64.h @@ -32,8 +32,8 @@ const unsigned kInstructionSizeLog2 = 2; const unsigned kLoadLiteralScaleLog2 = 2; const unsigned kMaxLoadLiteralRange = 1 * MB; -const unsigned kNumberOfRegisters = 32; -const unsigned kNumberOfFPRegisters = 32; +const int kNumberOfRegisters = 32; +const int kNumberOfFPRegisters = 32; // Callee saved registers are x19-x30(lr). const int kNumberOfCalleeSavedRegisters = 11; const int kFirstCalleeSavedRegisterIndex = 19; @@ -42,23 +42,22 @@ const int kNumberOfCalleeSavedFPRegisters = 8; const int kFirstCalleeSavedFPRegisterIndex = 8; // Callee saved registers with no specific purpose in JS are x19-x25. const unsigned kJSCalleeSavedRegList = 0x03f80000; -// TODO(all): kRegSize should probably be kRegSizeInBits. -const unsigned kWRegSizeInBits = 32; -const unsigned kWRegSizeInBitsLog2 = 5; -const unsigned kWRegSize = kWRegSizeInBits >> 3; -const unsigned kWRegSizeLog2 = kWRegSizeInBitsLog2 - 3; -const unsigned kXRegSizeInBits = 64; -const unsigned kXRegSizeInBitsLog2 = 6; -const unsigned kXRegSize = kXRegSizeInBits >> 3; -const unsigned kXRegSizeLog2 = kXRegSizeInBitsLog2 - 3; -const unsigned kSRegSizeInBits = 32; -const unsigned kSRegSizeInBitsLog2 = 5; -const unsigned kSRegSize = kSRegSizeInBits >> 3; -const unsigned kSRegSizeLog2 = kSRegSizeInBitsLog2 - 3; -const unsigned kDRegSizeInBits = 64; -const unsigned kDRegSizeInBitsLog2 = 6; -const unsigned kDRegSize = kDRegSizeInBits >> 3; -const unsigned kDRegSizeLog2 = kDRegSizeInBitsLog2 - 3; +const int kWRegSizeInBits = 32; +const int kWRegSizeInBitsLog2 = 5; +const int kWRegSize = kWRegSizeInBits >> 3; +const int kWRegSizeLog2 = kWRegSizeInBitsLog2 - 3; +const int kXRegSizeInBits = 64; +const int kXRegSizeInBitsLog2 = 6; +const int kXRegSize = kXRegSizeInBits >> 3; +const int kXRegSizeLog2 = kXRegSizeInBitsLog2 - 3; +const int kSRegSizeInBits = 32; +const int kSRegSizeInBitsLog2 = 5; +const int kSRegSize = kSRegSizeInBits >> 3; +const int kSRegSizeLog2 = kSRegSizeInBitsLog2 - 3; +const int kDRegSizeInBits = 64; +const int kDRegSizeInBitsLog2 = 6; +const int kDRegSize = kDRegSizeInBits >> 3; +const int kDRegSizeLog2 = kDRegSizeInBitsLog2 - 3; const int64_t kWRegMask = 0x00000000ffffffffL; const int64_t kXRegMask = 0xffffffffffffffffL; const int64_t kSRegMask = 0x00000000ffffffffL; @@ -86,13 +85,13 @@ const int64_t kXMaxInt = 0x7fffffffffffffffL; const int64_t kXMinInt = 0x8000000000000000L; const int32_t kWMaxInt = 0x7fffffff; const int32_t kWMinInt = 0x80000000; -const unsigned kIp0Code = 16; -const unsigned kIp1Code = 17; -const unsigned kFramePointerRegCode = 29; -const unsigned kLinkRegCode = 30; -const unsigned kZeroRegCode = 31; -const unsigned kJSSPCode = 28; -const unsigned kSPRegInternalCode = 63; +const int kIp0Code = 16; +const int kIp1Code = 17; +const int kFramePointerRegCode = 29; +const int kLinkRegCode = 30; +const int kZeroRegCode = 31; +const int kJSSPCode = 28; +const int kSPRegInternalCode = 63; const unsigned kRegCodeMask = 0x1f; const unsigned kShiftAmountWRegMask = 0x1f; const unsigned kShiftAmountXRegMask = 0x3f; @@ -118,12 +117,6 @@ const unsigned kDoubleExponentBias = 1023; const unsigned kFloatMantissaBits = 23; const unsigned kFloatExponentBits = 8; -#define REGISTER_CODE_LIST(R) \ -R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ -R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ -R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ -R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) - #define INSTRUCTION_FIELDS_LIST(V_) \ /* Register fields */ \ V_(Rd, 4, 0, Bits) /* Destination register. */ \ @@ -1237,6 +1230,7 @@ enum UnallocatedOp { UnallocatedFMask = 0x00000000 }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_CONSTANTS_ARM64_H_ diff --git a/deps/v8/src/arm64/decoder-arm64-inl.h b/deps/v8/src/arm64/decoder-arm64-inl.h index c29f2d3c5ed3ad..e00105e7bc1b49 100644 --- a/deps/v8/src/arm64/decoder-arm64-inl.h +++ b/deps/v8/src/arm64/decoder-arm64-inl.h @@ -644,6 +644,7 @@ void Decoder::DecodeAdvSIMDDataProcessing(Instruction* instr) { } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_DECODER_ARM64_INL_H_ diff --git a/deps/v8/src/arm64/decoder-arm64.h b/deps/v8/src/arm64/decoder-arm64.h index 6140bc2818077b..b1ef41f1a2fe72 100644 --- a/deps/v8/src/arm64/decoder-arm64.h +++ b/deps/v8/src/arm64/decoder-arm64.h @@ -181,6 +181,7 @@ class Decoder : public V { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_DECODER_ARM64_H_ diff --git a/deps/v8/src/arm64/deoptimizer-arm64.cc b/deps/v8/src/arm64/deoptimizer-arm64.cc index 65fb93e53cfa2e..19ee123b369b42 100644 --- a/deps/v8/src/arm64/deoptimizer-arm64.cc +++ b/deps/v8/src/arm64/deoptimizer-arm64.cc @@ -6,6 +6,7 @@ #include "src/codegen.h" #include "src/deoptimizer.h" #include "src/full-codegen/full-codegen.h" +#include "src/register-configuration.h" #include "src/safepoint-table.h" @@ -75,7 +76,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { input_->SetRegister(jssp.code(), reinterpret_cast(frame->sp())); input_->SetRegister(fp.code(), reinterpret_cast(frame->fp())); - for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { + for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { input_->SetDoubleRegister(i, 0.0); } @@ -122,8 +123,10 @@ void Deoptimizer::TableEntryGenerator::Generate() { // in the input frame. // Save all allocatable floating point registers. - CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSizeInBits, - FPRegister::kAllocatableFPRegisters); + CPURegList saved_fp_registers( + CPURegister::kFPRegister, kDRegSizeInBits, + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->allocatable_double_codes_mask()); __ PushCPURegList(saved_fp_registers); // We save all the registers expcept jssp, sp and lr. diff --git a/deps/v8/src/arm64/disasm-arm64.cc b/deps/v8/src/arm64/disasm-arm64.cc index fb3b692d08f5af..00c3ec25d6a763 100644 --- a/deps/v8/src/arm64/disasm-arm64.cc +++ b/deps/v8/src/arm64/disasm-arm64.cc @@ -19,7 +19,7 @@ namespace v8 { namespace internal { -Disassembler::Disassembler() { +DisassemblingDecoder::DisassemblingDecoder() { buffer_size_ = 256; buffer_ = reinterpret_cast(malloc(buffer_size_)); buffer_pos_ = 0; @@ -27,7 +27,7 @@ Disassembler::Disassembler() { } -Disassembler::Disassembler(char* text_buffer, int buffer_size) { +DisassemblingDecoder::DisassemblingDecoder(char* text_buffer, int buffer_size) { buffer_size_ = buffer_size; buffer_ = text_buffer; buffer_pos_ = 0; @@ -35,19 +35,17 @@ Disassembler::Disassembler(char* text_buffer, int buffer_size) { } -Disassembler::~Disassembler() { +DisassemblingDecoder::~DisassemblingDecoder() { if (own_buffer_) { free(buffer_); } } -char* Disassembler::GetOutput() { - return buffer_; -} +char* DisassemblingDecoder::GetOutput() { return buffer_; } -void Disassembler::VisitAddSubImmediate(Instruction* instr) { +void DisassemblingDecoder::VisitAddSubImmediate(Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool stack_op = (rd_is_zr || RnIsZROrSP(instr)) && (instr->ImmAddSub() == 0) ? true : false; @@ -92,7 +90,7 @@ void Disassembler::VisitAddSubImmediate(Instruction* instr) { } -void Disassembler::VisitAddSubShifted(Instruction* instr) { +void DisassemblingDecoder::VisitAddSubShifted(Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; @@ -139,7 +137,7 @@ void Disassembler::VisitAddSubShifted(Instruction* instr) { } -void Disassembler::VisitAddSubExtended(Instruction* instr) { +void DisassemblingDecoder::VisitAddSubExtended(Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); const char *mnemonic = ""; Extend mode = static_cast(instr->ExtendMode()); @@ -177,7 +175,7 @@ void Disassembler::VisitAddSubExtended(Instruction* instr) { } -void Disassembler::VisitAddSubWithCarry(Instruction* instr) { +void DisassemblingDecoder::VisitAddSubWithCarry(Instruction* instr) { bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; const char *form = "'Rd, 'Rn, 'Rm"; @@ -212,7 +210,7 @@ void Disassembler::VisitAddSubWithCarry(Instruction* instr) { } -void Disassembler::VisitLogicalImmediate(Instruction* instr) { +void DisassemblingDecoder::VisitLogicalImmediate(Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; @@ -255,7 +253,7 @@ void Disassembler::VisitLogicalImmediate(Instruction* instr) { } -bool Disassembler::IsMovzMovnImm(unsigned reg_size, uint64_t value) { +bool DisassemblingDecoder::IsMovzMovnImm(unsigned reg_size, uint64_t value) { DCHECK((reg_size == kXRegSizeInBits) || ((reg_size == kWRegSizeInBits) && (value <= 0xffffffff))); @@ -284,7 +282,7 @@ bool Disassembler::IsMovzMovnImm(unsigned reg_size, uint64_t value) { } -void Disassembler::VisitLogicalShifted(Instruction* instr) { +void DisassemblingDecoder::VisitLogicalShifted(Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; @@ -335,7 +333,7 @@ void Disassembler::VisitLogicalShifted(Instruction* instr) { } -void Disassembler::VisitConditionalCompareRegister(Instruction* instr) { +void DisassemblingDecoder::VisitConditionalCompareRegister(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rn, 'Rm, 'INzcv, 'Cond"; @@ -350,7 +348,8 @@ void Disassembler::VisitConditionalCompareRegister(Instruction* instr) { } -void Disassembler::VisitConditionalCompareImmediate(Instruction* instr) { +void DisassemblingDecoder::VisitConditionalCompareImmediate( + Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rn, 'IP, 'INzcv, 'Cond"; @@ -365,7 +364,7 @@ void Disassembler::VisitConditionalCompareImmediate(Instruction* instr) { } -void Disassembler::VisitConditionalSelect(Instruction* instr) { +void DisassemblingDecoder::VisitConditionalSelect(Instruction* instr) { bool rnm_is_zr = (RnIsZROrSP(instr) && RmIsZROrSP(instr)); bool rn_is_rm = (instr->Rn() == instr->Rm()); const char *mnemonic = ""; @@ -418,7 +417,7 @@ void Disassembler::VisitConditionalSelect(Instruction* instr) { } -void Disassembler::VisitBitfield(Instruction* instr) { +void DisassemblingDecoder::VisitBitfield(Instruction* instr) { unsigned s = instr->ImmS(); unsigned r = instr->ImmR(); unsigned rd_size_minus_1 = @@ -496,7 +495,7 @@ void Disassembler::VisitBitfield(Instruction* instr) { } -void Disassembler::VisitExtract(Instruction* instr) { +void DisassemblingDecoder::VisitExtract(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'Rn, 'Rm, 'IExtract"; @@ -517,7 +516,7 @@ void Disassembler::VisitExtract(Instruction* instr) { } -void Disassembler::VisitPCRelAddressing(Instruction* instr) { +void DisassemblingDecoder::VisitPCRelAddressing(Instruction* instr) { switch (instr->Mask(PCRelAddressingMask)) { case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break; // ADRP is not implemented. @@ -526,7 +525,7 @@ void Disassembler::VisitPCRelAddressing(Instruction* instr) { } -void Disassembler::VisitConditionalBranch(Instruction* instr) { +void DisassemblingDecoder::VisitConditionalBranch(Instruction* instr) { switch (instr->Mask(ConditionalBranchMask)) { case B_cond: Format(instr, "b.'CBrn", "'BImmCond"); break; default: UNREACHABLE(); @@ -534,7 +533,8 @@ void Disassembler::VisitConditionalBranch(Instruction* instr) { } -void Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) { +void DisassemblingDecoder::VisitUnconditionalBranchToRegister( + Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Xn"; @@ -554,7 +554,7 @@ void Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) { } -void Disassembler::VisitUnconditionalBranch(Instruction* instr) { +void DisassemblingDecoder::VisitUnconditionalBranch(Instruction* instr) { const char *mnemonic = ""; const char *form = "'BImmUncn"; @@ -567,7 +567,7 @@ void Disassembler::VisitUnconditionalBranch(Instruction* instr) { } -void Disassembler::VisitDataProcessing1Source(Instruction* instr) { +void DisassemblingDecoder::VisitDataProcessing1Source(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'Rn"; @@ -588,7 +588,7 @@ void Disassembler::VisitDataProcessing1Source(Instruction* instr) { } -void Disassembler::VisitDataProcessing2Source(Instruction* instr) { +void DisassemblingDecoder::VisitDataProcessing2Source(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Rd, 'Rn, 'Rm"; @@ -609,7 +609,7 @@ void Disassembler::VisitDataProcessing2Source(Instruction* instr) { } -void Disassembler::VisitDataProcessing3Source(Instruction* instr) { +void DisassemblingDecoder::VisitDataProcessing3Source(Instruction* instr) { bool ra_is_zr = RaIsZROrSP(instr); const char *mnemonic = ""; const char *form = "'Xd, 'Wn, 'Wm, 'Xa"; @@ -687,7 +687,7 @@ void Disassembler::VisitDataProcessing3Source(Instruction* instr) { } -void Disassembler::VisitCompareBranch(Instruction* instr) { +void DisassemblingDecoder::VisitCompareBranch(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rt, 'BImmCmpa"; @@ -702,7 +702,7 @@ void Disassembler::VisitCompareBranch(Instruction* instr) { } -void Disassembler::VisitTestBranch(Instruction* instr) { +void DisassemblingDecoder::VisitTestBranch(Instruction* instr) { const char *mnemonic = ""; // If the top bit of the immediate is clear, the tested register is // disassembled as Wt, otherwise Xt. As the top bit of the immediate is @@ -719,7 +719,7 @@ void Disassembler::VisitTestBranch(Instruction* instr) { } -void Disassembler::VisitMoveWideImmediate(Instruction* instr) { +void DisassemblingDecoder::VisitMoveWideImmediate(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'IMoveImm"; @@ -758,7 +758,7 @@ void Disassembler::VisitMoveWideImmediate(Instruction* instr) { V(LDR_s, "ldr", "'St") \ V(LDR_d, "ldr", "'Dt") -void Disassembler::VisitLoadStorePreIndex(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStorePreIndex(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePreIndex)"; @@ -772,7 +772,7 @@ void Disassembler::VisitLoadStorePreIndex(Instruction* instr) { } -void Disassembler::VisitLoadStorePostIndex(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStorePostIndex(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePostIndex)"; @@ -786,7 +786,7 @@ void Disassembler::VisitLoadStorePostIndex(Instruction* instr) { } -void Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStoreUnsignedOffset(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStoreUnsignedOffset)"; @@ -801,7 +801,7 @@ void Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) { } -void Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStoreRegisterOffset(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStoreRegisterOffset)"; @@ -816,7 +816,7 @@ void Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) { } -void Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStoreUnscaledOffset(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Wt, ['Xns'ILS]"; const char *form_x = "'Xt, ['Xns'ILS]"; @@ -847,7 +847,7 @@ void Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) { } -void Disassembler::VisitLoadLiteral(Instruction* instr) { +void DisassemblingDecoder::VisitLoadLiteral(Instruction* instr) { const char *mnemonic = "ldr"; const char *form = "(LoadLiteral)"; @@ -873,7 +873,7 @@ void Disassembler::VisitLoadLiteral(Instruction* instr) { V(STP_d, "stp", "'Dt, 'Dt2", "8") \ V(LDP_d, "ldp", "'Dt, 'Dt2", "8") -void Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStorePairPostIndex(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairPostIndex)"; @@ -887,7 +887,7 @@ void Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) { } -void Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStorePairPreIndex(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairPreIndex)"; @@ -901,7 +901,7 @@ void Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) { } -void Disassembler::VisitLoadStorePairOffset(Instruction* instr) { +void DisassemblingDecoder::VisitLoadStorePairOffset(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairOffset)"; @@ -915,7 +915,7 @@ void Disassembler::VisitLoadStorePairOffset(Instruction* instr) { } -void Disassembler::VisitFPCompare(Instruction* instr) { +void DisassemblingDecoder::VisitFPCompare(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Fn, 'Fm"; const char *form_zero = "'Fn, #0.0"; @@ -931,7 +931,7 @@ void Disassembler::VisitFPCompare(Instruction* instr) { } -void Disassembler::VisitFPConditionalCompare(Instruction* instr) { +void DisassemblingDecoder::VisitFPConditionalCompare(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Fn, 'Fm, 'INzcv, 'Cond"; @@ -946,7 +946,7 @@ void Disassembler::VisitFPConditionalCompare(Instruction* instr) { } -void Disassembler::VisitFPConditionalSelect(Instruction* instr) { +void DisassemblingDecoder::VisitFPConditionalSelect(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Fd, 'Fn, 'Fm, 'Cond"; @@ -959,7 +959,7 @@ void Disassembler::VisitFPConditionalSelect(Instruction* instr) { } -void Disassembler::VisitFPDataProcessing1Source(Instruction* instr) { +void DisassemblingDecoder::VisitFPDataProcessing1Source(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Fd, 'Fn"; @@ -987,7 +987,7 @@ void Disassembler::VisitFPDataProcessing1Source(Instruction* instr) { } -void Disassembler::VisitFPDataProcessing2Source(Instruction* instr) { +void DisassemblingDecoder::VisitFPDataProcessing2Source(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Fd, 'Fn, 'Fm"; @@ -1011,7 +1011,7 @@ void Disassembler::VisitFPDataProcessing2Source(Instruction* instr) { } -void Disassembler::VisitFPDataProcessing3Source(Instruction* instr) { +void DisassemblingDecoder::VisitFPDataProcessing3Source(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Fd, 'Fn, 'Fm, 'Fa"; @@ -1030,7 +1030,7 @@ void Disassembler::VisitFPDataProcessing3Source(Instruction* instr) { } -void Disassembler::VisitFPImmediate(Instruction* instr) { +void DisassemblingDecoder::VisitFPImmediate(Instruction* instr) { const char *mnemonic = ""; const char *form = "(FPImmediate)"; @@ -1043,7 +1043,7 @@ void Disassembler::VisitFPImmediate(Instruction* instr) { } -void Disassembler::VisitFPIntegerConvert(Instruction* instr) { +void DisassemblingDecoder::VisitFPIntegerConvert(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(FPIntegerConvert)"; const char *form_rf = "'Rd, 'Fn"; @@ -1099,7 +1099,7 @@ void Disassembler::VisitFPIntegerConvert(Instruction* instr) { } -void Disassembler::VisitFPFixedPointConvert(Instruction* instr) { +void DisassemblingDecoder::VisitFPFixedPointConvert(Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'Fn, 'IFPFBits"; const char *form_fr = "'Fd, 'Rn, 'IFPFBits"; @@ -1126,7 +1126,7 @@ void Disassembler::VisitFPFixedPointConvert(Instruction* instr) { } -void Disassembler::VisitSystem(Instruction* instr) { +void DisassemblingDecoder::VisitSystem(Instruction* instr) { // Some system instructions hijack their Op and Cp fields to represent a // range of immediates instead of indicating a different instruction. This // makes the decoding tricky. @@ -1187,7 +1187,7 @@ void Disassembler::VisitSystem(Instruction* instr) { } -void Disassembler::VisitException(Instruction* instr) { +void DisassemblingDecoder::VisitException(Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'IDebug"; @@ -1206,23 +1206,23 @@ void Disassembler::VisitException(Instruction* instr) { } -void Disassembler::VisitUnimplemented(Instruction* instr) { +void DisassemblingDecoder::VisitUnimplemented(Instruction* instr) { Format(instr, "unimplemented", "(Unimplemented)"); } -void Disassembler::VisitUnallocated(Instruction* instr) { +void DisassemblingDecoder::VisitUnallocated(Instruction* instr) { Format(instr, "unallocated", "(Unallocated)"); } -void Disassembler::ProcessOutput(Instruction* /*instr*/) { +void DisassemblingDecoder::ProcessOutput(Instruction* /*instr*/) { // The base disasm does nothing more than disassembling into a buffer. } -void Disassembler::Format(Instruction* instr, const char* mnemonic, - const char* format) { +void DisassemblingDecoder::Format(Instruction* instr, const char* mnemonic, + const char* format) { // TODO(mcapewel) don't think I can use the instr address here - there needs // to be a base address too DCHECK(mnemonic != NULL); @@ -1237,7 +1237,7 @@ void Disassembler::Format(Instruction* instr, const char* mnemonic, } -void Disassembler::Substitute(Instruction* instr, const char* string) { +void DisassemblingDecoder::Substitute(Instruction* instr, const char* string) { char chr = *string++; while (chr != '\0') { if (chr == '\'') { @@ -1250,7 +1250,8 @@ void Disassembler::Substitute(Instruction* instr, const char* string) { } -int Disassembler::SubstituteField(Instruction* instr, const char* format) { +int DisassemblingDecoder::SubstituteField(Instruction* instr, + const char* format) { switch (format[0]) { case 'R': // Register. X or W, selected by sf bit. case 'F': // FP Register. S or D, selected by type field. @@ -1276,8 +1277,8 @@ int Disassembler::SubstituteField(Instruction* instr, const char* format) { } -int Disassembler::SubstituteRegisterField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteRegisterField(Instruction* instr, + const char* format) { unsigned reg_num = 0; unsigned field_len = 2; switch (format[1]) { @@ -1341,8 +1342,8 @@ int Disassembler::SubstituteRegisterField(Instruction* instr, } -int Disassembler::SubstituteImmediateField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr, + const char* format) { DCHECK(format[0] == 'I'); switch (format[1]) { @@ -1452,8 +1453,8 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, } -int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteBitfieldImmediateField(Instruction* instr, + const char* format) { DCHECK((format[0] == 'I') && (format[1] == 'B')); unsigned r = instr->ImmR(); unsigned s = instr->ImmS(); @@ -1488,8 +1489,8 @@ int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr, } -int Disassembler::SubstituteLiteralField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteLiteralField(Instruction* instr, + const char* format) { DCHECK(strncmp(format, "LValue", 6) == 0); USE(format); @@ -1507,7 +1508,8 @@ int Disassembler::SubstituteLiteralField(Instruction* instr, } -int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) { +int DisassemblingDecoder::SubstituteShiftField(Instruction* instr, + const char* format) { DCHECK(format[0] == 'H'); DCHECK(instr->ShiftDP() <= 0x3); @@ -1530,8 +1532,8 @@ int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) { } -int Disassembler::SubstituteConditionField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteConditionField(Instruction* instr, + const char* format) { DCHECK(format[0] == 'C'); const char* condition_code[] = { "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc", @@ -1551,8 +1553,8 @@ int Disassembler::SubstituteConditionField(Instruction* instr, } -int Disassembler::SubstitutePCRelAddressField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstitutePCRelAddressField(Instruction* instr, + const char* format) { USE(format); DCHECK(strncmp(format, "AddrPCRel", 9) == 0); @@ -1572,8 +1574,8 @@ int Disassembler::SubstitutePCRelAddressField(Instruction* instr, } -int Disassembler::SubstituteBranchTargetField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteBranchTargetField(Instruction* instr, + const char* format) { DCHECK(strncmp(format, "BImm", 4) == 0); int64_t offset = 0; @@ -1599,8 +1601,8 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr, } -int Disassembler::SubstituteExtendField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteExtendField(Instruction* instr, + const char* format) { DCHECK(strncmp(format, "Ext", 3) == 0); DCHECK(instr->ExtendMode() <= 7); USE(format); @@ -1626,8 +1628,8 @@ int Disassembler::SubstituteExtendField(Instruction* instr, } -int Disassembler::SubstituteLSRegOffsetField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteLSRegOffsetField(Instruction* instr, + const char* format) { DCHECK(strncmp(format, "Offsetreg", 9) == 0); const char* extend_mode[] = { "undefined", "undefined", "uxtw", "lsl", "undefined", "undefined", "sxtw", "sxtx" }; @@ -1655,8 +1657,8 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr, } -int Disassembler::SubstitutePrefetchField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstitutePrefetchField(Instruction* instr, + const char* format) { DCHECK(format[0] == 'P'); USE(format); @@ -1670,8 +1672,8 @@ int Disassembler::SubstitutePrefetchField(Instruction* instr, return 6; } -int Disassembler::SubstituteBarrierField(Instruction* instr, - const char* format) { +int DisassemblingDecoder::SubstituteBarrierField(Instruction* instr, + const char* format) { DCHECK(format[0] == 'M'); USE(format); @@ -1689,13 +1691,13 @@ int Disassembler::SubstituteBarrierField(Instruction* instr, } -void Disassembler::ResetOutput() { +void DisassemblingDecoder::ResetOutput() { buffer_pos_ = 0; buffer_[buffer_pos_] = 0; } -void Disassembler::AppendToOutput(const char* format, ...) { +void DisassemblingDecoder::AppendToOutput(const char* format, ...) { va_list args; va_start(args, format); buffer_pos_ += vsnprintf(&buffer_[buffer_pos_], buffer_size_, format, args); @@ -1761,7 +1763,7 @@ const char* NameConverter::NameInCode(byte* addr) const { //------------------------------------------------------------------------------ -class BufferDisassembler : public v8::internal::Disassembler { +class BufferDisassembler : public v8::internal::DisassemblingDecoder { public: explicit BufferDisassembler(v8::internal::Vector out_buffer) : out_buffer_(out_buffer) { } diff --git a/deps/v8/src/arm64/disasm-arm64.h b/deps/v8/src/arm64/disasm-arm64.h index c6b189bf97140c..4b477bc438e8f1 100644 --- a/deps/v8/src/arm64/disasm-arm64.h +++ b/deps/v8/src/arm64/disasm-arm64.h @@ -14,11 +14,11 @@ namespace v8 { namespace internal { -class Disassembler: public DecoderVisitor { +class DisassemblingDecoder : public DecoderVisitor { public: - Disassembler(); - Disassembler(char* text_buffer, int buffer_size); - virtual ~Disassembler(); + DisassemblingDecoder(); + DisassemblingDecoder(char* text_buffer, int buffer_size); + virtual ~DisassemblingDecoder(); char* GetOutput(); // Declare all Visitor functions. @@ -73,7 +73,7 @@ class Disassembler: public DecoderVisitor { }; -class PrintDisassembler: public Disassembler { +class PrintDisassembler : public DisassemblingDecoder { public: explicit PrintDisassembler(FILE* stream) : stream_(stream) { } ~PrintDisassembler() { } @@ -85,6 +85,7 @@ class PrintDisassembler: public Disassembler { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_DISASM_ARM64_H diff --git a/deps/v8/src/arm64/frames-arm64.h b/deps/v8/src/arm64/frames-arm64.h index 9e6551783da9b4..783514437f2829 100644 --- a/deps/v8/src/arm64/frames-arm64.h +++ b/deps/v8/src/arm64/frames-arm64.h @@ -63,6 +63,7 @@ class JavaScriptFrameConstants : public AllStatic { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_FRAMES_ARM64_H_ diff --git a/deps/v8/src/arm64/instructions-arm64.h b/deps/v8/src/arm64/instructions-arm64.h index 145a7c9053aa95..5c652e3ec8a56a 100644 --- a/deps/v8/src/arm64/instructions-arm64.h +++ b/deps/v8/src/arm64/instructions-arm64.h @@ -532,7 +532,8 @@ enum DebugParameters { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_INSTRUCTIONS_ARM64_H_ diff --git a/deps/v8/src/arm64/instrument-arm64.h b/deps/v8/src/arm64/instrument-arm64.h index 86ddfcbbc1ed37..02816e943e23b6 100644 --- a/deps/v8/src/arm64/instrument-arm64.h +++ b/deps/v8/src/arm64/instrument-arm64.h @@ -80,6 +80,7 @@ class Instrument: public DecoderVisitor { uint64_t sample_period_; }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_INSTRUMENT_ARM64_H_ diff --git a/deps/v8/src/arm64/interface-descriptors-arm64.cc b/deps/v8/src/arm64/interface-descriptors-arm64.cc index 3dac70e78448be..4e1b8180656f20 100644 --- a/deps/v8/src/arm64/interface-descriptors-arm64.cc +++ b/deps/v8/src/arm64/interface-descriptors-arm64.cc @@ -78,14 +78,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; } const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; } -void VectorStoreTransitionDescriptor::InitializePlatformSpecific( - CallInterfaceDescriptorData* data) { - Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(), - SlotRegister(), VectorRegister(), MapRegister()}; - data->InitializePlatformSpecific(arraysize(registers), registers); -} - - void FastNewClosureDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { // x2: function info @@ -110,6 +102,10 @@ void ToNumberDescriptor::InitializePlatformSpecific( } +// static +const Register ToLengthDescriptor::ReceiverRegister() { return x0; } + + // static const Register ToStringDescriptor::ReceiverRegister() { return x0; } @@ -250,6 +246,13 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific( } +void AllocateInNewSpaceDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + Register registers[] = {x0}; + data->InitializePlatformSpecific(arraysize(registers), registers); +} + + void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { // x1: function @@ -446,16 +449,40 @@ void MathRoundVariantCallFromOptimizedCodeDescriptor:: } -void PushArgsAndCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { - x0, // argument count (including receiver) + x0, // argument count (not including receiver) x2, // address of first argument x1 // the target callable to be call }; data->InitializePlatformSpecific(arraysize(registers), registers); } + +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + Register registers[] = { + x0, // argument count (not including receiver) + x3, // original constructor + x1, // constructor to call + x2 // address of the first argument + }; + data->InitializePlatformSpecific(arraysize(registers), registers); +} + + +void InterpreterCEntryDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + Register registers[] = { + x0, // argument count (argc) + x11, // address of first argument (argv) + x1 // the runtime function to call + }; + data->InitializePlatformSpecific(arraysize(registers), registers); +} + + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/arm64/interface-descriptors-arm64.h b/deps/v8/src/arm64/interface-descriptors-arm64.h index 76def88326a0bb..20ab8cb61243bc 100644 --- a/deps/v8/src/arm64/interface-descriptors-arm64.h +++ b/deps/v8/src/arm64/interface-descriptors-arm64.h @@ -20,7 +20,7 @@ class PlatformInterfaceDescriptor { private: TargetAddressStorageMode storage_mode_; }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_INTERFACE_DESCRIPTORS_ARM64_H_ diff --git a/deps/v8/src/arm64/macro-assembler-arm64-inl.h b/deps/v8/src/arm64/macro-assembler-arm64-inl.h index 445513bf5abb61..9b4abe55146959 100644 --- a/deps/v8/src/arm64/macro-assembler-arm64-inl.h +++ b/deps/v8/src/arm64/macro-assembler-arm64-inl.h @@ -1683,6 +1683,7 @@ void MacroAssembler::AnnotateInstrumentation(const char* marker_name) { movn(xzr, (marker_name[1] << 8) | marker_name[0]); } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ diff --git a/deps/v8/src/arm64/macro-assembler-arm64.cc b/deps/v8/src/arm64/macro-assembler-arm64.cc index 5e8abe72157f5c..5b941a2a5a5364 100644 --- a/deps/v8/src/arm64/macro-assembler-arm64.cc +++ b/deps/v8/src/arm64/macro-assembler-arm64.cc @@ -9,6 +9,7 @@ #include "src/bootstrapper.h" #include "src/codegen.h" #include "src/debug/debug.h" +#include "src/register-configuration.h" #include "src/runtime/runtime.h" #include "src/arm64/frames-arm64.h" @@ -35,8 +36,8 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, tmp_list_(DefaultTmpList()), fptmp_list_(DefaultFPTmpList()) { if (isolate() != NULL) { - code_object_ = Handle(isolate()->heap()->undefined_value(), - isolate()); + code_object_ = + Handle::New(isolate()->heap()->undefined_value(), isolate()); } } @@ -208,7 +209,7 @@ void MacroAssembler::Mov(const Register& rd, uint64_t imm) { // halfword, and movk for subsequent halfwords. DCHECK((reg_size % 16) == 0); bool first_mov_done = false; - for (unsigned i = 0; i < (rd.SizeInBits() / 16); i++) { + for (int i = 0; i < (rd.SizeInBits() / 16); i++) { uint64_t imm16 = (imm >> (16 * i)) & 0xffffL; if (imm16 != ignored_halfword) { if (!first_mov_done) { @@ -1704,7 +1705,7 @@ void MacroAssembler::GetBuiltinFunction(Register target, int native_context_index) { // Load the builtins object into target register. Ldr(target, GlobalObjectMemOperand()); - Ldr(target, FieldMemOperand(target, GlobalObject::kNativeContextOffset)); + Ldr(target, FieldMemOperand(target, JSGlobalObject::kNativeContextOffset)); // Load the JavaScript builtin function from the builtins object. Ldr(target, ContextMemOperand(target, native_context_index)); } @@ -2423,9 +2424,10 @@ void MacroAssembler::JumpIfEitherInstanceTypeIsNotSequentialOneByte( Label* failure) { DCHECK(!AreAliased(scratch1, second)); DCHECK(!AreAliased(scratch1, scratch2)); - static const int kFlatOneByteStringMask = + const int kFlatOneByteStringMask = kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; - static const int kFlatOneByteStringTag = ONE_BYTE_STRING_TYPE; + const int kFlatOneByteStringTag = + kStringTag | kOneByteStringTag | kSeqStringTag; And(scratch1, first, kFlatOneByteStringMask); And(scratch2, second, kFlatOneByteStringMask); Cmp(scratch1, kFlatOneByteStringTag); @@ -3000,7 +3002,7 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) { void MacroAssembler::LoadGlobalProxy(Register dst) { Ldr(dst, GlobalObjectMemOperand()); - Ldr(dst, FieldMemOperand(dst, GlobalObject::kGlobalProxyOffset)); + Ldr(dst, FieldMemOperand(dst, JSGlobalObject::kGlobalProxyOffset)); } @@ -3570,6 +3572,14 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Register result, } +void MacroAssembler::PushRoot(Heap::RootListIndex index) { + UseScratchRegisterScope temps(this); + Register temp = temps.AcquireX(); + LoadRoot(temp, index); + Push(temp); +} + + void MacroAssembler::CompareRoot(const Register& obj, Heap::RootListIndex index) { UseScratchRegisterScope temps(this); @@ -3772,7 +3782,8 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, int offset = Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; Ldr(scratch1, FieldMemOperand(scratch1, offset)); - Ldr(scratch1, FieldMemOperand(scratch1, GlobalObject::kNativeContextOffset)); + Ldr(scratch1, + FieldMemOperand(scratch1, JSGlobalObject::kNativeContextOffset)); // Check the context is a native context. if (emit_debug_code()) { @@ -3984,14 +3995,18 @@ void MacroAssembler::PushSafepointRegisters() { void MacroAssembler::PushSafepointRegistersAndDoubles() { PushSafepointRegisters(); - PushCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, - FPRegister::kAllocatableFPRegisters)); + PushCPURegList(CPURegList( + CPURegister::kFPRegister, kDRegSizeInBits, + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->allocatable_double_codes_mask())); } void MacroAssembler::PopSafepointRegistersAndDoubles() { - PopCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, - FPRegister::kAllocatableFPRegisters)); + PopCPURegList(CPURegList( + CPURegister::kFPRegister, kDRegSizeInBits, + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->allocatable_double_codes_mask())); PopSafepointRegisters(); } @@ -4602,7 +4617,8 @@ void MacroAssembler::LoadTransitionedArrayMapConditional( Label* no_map_match) { // Load the global or builtins object from the current context. Ldr(scratch1, GlobalObjectMemOperand()); - Ldr(scratch1, FieldMemOperand(scratch1, GlobalObject::kNativeContextOffset)); + Ldr(scratch1, + FieldMemOperand(scratch1, JSGlobalObject::kNativeContextOffset)); // Check that the function's map is the same as the expected cached map. Ldr(scratch1, ContextMemOperand(scratch1, Context::JS_ARRAY_MAPS_INDEX)); @@ -4621,8 +4637,8 @@ void MacroAssembler::LoadGlobalFunction(int index, Register function) { // Load the global or builtins object from the current context. Ldr(function, GlobalObjectMemOperand()); // Load the native context from the global or builtins object. - Ldr(function, FieldMemOperand(function, - GlobalObject::kNativeContextOffset)); + Ldr(function, + FieldMemOperand(function, JSGlobalObject::kNativeContextOffset)); // Load the function from the native context. Ldr(function, ContextMemOperand(function, index)); } diff --git a/deps/v8/src/arm64/macro-assembler-arm64.h b/deps/v8/src/arm64/macro-assembler-arm64.h index 769140d9170d9e..2747397993e794 100644 --- a/deps/v8/src/arm64/macro-assembler-arm64.h +++ b/deps/v8/src/arm64/macro-assembler-arm64.h @@ -44,6 +44,7 @@ namespace internal { #define kInterpreterBytecodeOffsetRegister x19 #define kInterpreterBytecodeArrayRegister x20 #define kInterpreterDispatchTableRegister x21 +#define kJavaScriptCallArgCountRegister x0 #define kRuntimeCallFunctionRegister x1 #define kRuntimeCallArgCountRegister x0 @@ -1461,6 +1462,9 @@ class MacroAssembler : public Assembler { // register. void LoadElementsKindFromMap(Register result, Register map); + // Load the value from the root list and push it onto the stack. + void PushRoot(Heap::RootListIndex index); + // Compare the object in a register to a value from the root list. void CompareRoot(const Register& obj, Heap::RootListIndex index); @@ -2278,7 +2282,8 @@ class InlineSmiCheckInfo { class DeltaBits : public BitField {}; }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #ifdef GENERATED_CODE_COVERAGE #error "Unsupported option" diff --git a/deps/v8/src/arm64/simulator-arm64.h b/deps/v8/src/arm64/simulator-arm64.h index e4d9a81ffdbe3d..3d7c15cfd0053f 100644 --- a/deps/v8/src/arm64/simulator-arm64.h +++ b/deps/v8/src/arm64/simulator-arm64.h @@ -17,12 +17,6 @@ #include "src/globals.h" #include "src/utils.h" -#define REGISTER_CODE_LIST(R) \ -R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ -R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ -R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ -R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) - namespace v8 { namespace internal { @@ -911,6 +905,7 @@ class SimulatorStack : public v8::internal::AllStatic { #endif // !defined(USE_SIMULATOR) -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_SIMULATOR_ARM64_H_ diff --git a/deps/v8/src/arm64/utils-arm64.h b/deps/v8/src/arm64/utils-arm64.h index da91fd5d6000ae..1e1c0a33c24fb9 100644 --- a/deps/v8/src/arm64/utils-arm64.h +++ b/deps/v8/src/arm64/utils-arm64.h @@ -9,12 +9,6 @@ #include "src/arm64/constants-arm64.h" -#define REGISTER_CODE_LIST(R) \ -R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ -R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ -R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ -R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) - namespace v8 { namespace internal { @@ -151,6 +145,7 @@ inline float FusedMultiplyAdd(float op1, float op2, float a) { return fmaf(op1, op2, a); } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ARM64_UTILS_ARM64_H_ diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc index dd05a07750d12d..8571f331760337 100644 --- a/deps/v8/src/assembler.cc +++ b/deps/v8/src/assembler.cc @@ -46,13 +46,16 @@ #include "src/counters.h" #include "src/debug/debug.h" #include "src/deoptimizer.h" +#include "src/disassembler.h" #include "src/execution.h" #include "src/ic/ic.h" #include "src/ic/stub-cache.h" +#include "src/ostreams.h" #include "src/profiler/cpu-profiler.h" #include "src/regexp/jsregexp.h" #include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-stack.h" +#include "src/register-configuration.h" #include "src/runtime/runtime.h" #include "src/simulator.h" // For flushing instruction cache. #include "src/snapshot/serialize.h" @@ -104,6 +107,39 @@ namespace v8 { namespace internal { +// ----------------------------------------------------------------------------- +// Common register code. + +const char* Register::ToString() { + // This is the mapping of allocation indices to registers. + DCHECK(reg_code >= 0 && reg_code < kNumRegisters); + return RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->GetGeneralRegisterName(reg_code); +} + + +bool Register::IsAllocatable() const { + return ((1 << reg_code) & + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->allocatable_general_codes_mask()) != 0; +} + + +const char* DoubleRegister::ToString() { + // This is the mapping of allocation indices to registers. + DCHECK(reg_code >= 0 && reg_code < kMaxNumRegisters); + return RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->GetDoubleRegisterName(reg_code); +} + + +bool DoubleRegister::IsAllocatable() const { + return ((1 << reg_code) & + RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) + ->allocatable_double_codes_mask()) != 0; +} + + // ----------------------------------------------------------------------------- // Common double constants. @@ -181,6 +217,12 @@ void AssemblerBase::FlushICacheWithoutIsolate(void* start, size_t size) { } +void AssemblerBase::Print() { + OFStream os(stdout); + v8::internal::Disassembler::Decode(isolate(), &os, buffer_, pc_, nullptr); +} + + // ----------------------------------------------------------------------------- // Implementation of PredictableCodeSizeScope @@ -1407,9 +1449,21 @@ ExternalReference } -ExternalReference ExternalReference::vector_store_virtual_register( +ExternalReference ExternalReference::virtual_handler_register( + Isolate* isolate) { + return ExternalReference(isolate->virtual_handler_register_address()); +} + + +ExternalReference ExternalReference::virtual_slot_register(Isolate* isolate) { + return ExternalReference(isolate->virtual_slot_register_address()); +} + + +ExternalReference ExternalReference::runtime_function_table_address( Isolate* isolate) { - return ExternalReference(isolate->vector_store_virtual_register_address()); + return ExternalReference( + const_cast(Runtime::RuntimeFunctionTable(isolate))); } diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h index 433b9b8456dc86..1243adf468cbc9 100644 --- a/deps/v8/src/assembler.h +++ b/deps/v8/src/assembler.h @@ -49,6 +49,7 @@ class ApiFunction; namespace internal { // Forward declarations. +class SourcePosition; class StatsCounter; // ----------------------------------------------------------------------------- @@ -99,6 +100,9 @@ class AssemblerBase: public Malloced { // the assembler could clean up internal data structures. virtual void AbortedCodeGeneration() { } + // Debugging + void Print(); + static const int kMinimalBufferSize = 4*KB; static void FlushICache(Isolate* isolate, void* start, size_t size); @@ -319,6 +323,8 @@ class Label { enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs }; +enum ArgvMode { kArgvOnStack, kArgvInRegister }; + // Specifies whether to perform icache flush operations on RelocInfo updates. // If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an // instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be @@ -659,11 +665,6 @@ class RelocInfo { Mode rmode_; intptr_t data_; Code* host_; - // External-reference pointers are also split across instruction-pairs - // on some platforms, but are accessed via indirect pointers. This location - // provides a place for that pointer to exist naturally. Its address - // is returned by RelocInfo::target_reference_address(). - Address reconstructed_adr_ptr_; friend class RelocIterator; }; @@ -990,7 +991,10 @@ class ExternalReference BASE_EMBEDDED { static ExternalReference invoke_function_callback(Isolate* isolate); static ExternalReference invoke_accessor_getter_callback(Isolate* isolate); - static ExternalReference vector_store_virtual_register(Isolate* isolate); + static ExternalReference virtual_handler_register(Isolate* isolate); + static ExternalReference virtual_slot_register(Isolate* isolate); + + static ExternalReference runtime_function_table_address(Isolate* isolate); Address address() const { return reinterpret_cast
(address_); } @@ -1276,7 +1280,6 @@ class ConstantPoolBuilder BASE_EMBEDDED { PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES]; }; - -} } // namespace v8::internal - +} // namespace internal +} // namespace v8 #endif // V8_ASSEMBLER_H_ diff --git a/deps/v8/src/assert-scope.h b/deps/v8/src/assert-scope.h index 8757a329100588..84e6990b04b353 100644 --- a/deps/v8/src/assert-scope.h +++ b/deps/v8/src/assert-scope.h @@ -170,6 +170,7 @@ typedef PerIsolateAssertScopeDebugOnly // Scope to introduce an exception to DisallowDeoptimization. typedef PerIsolateAssertScopeDebugOnly AllowCompilation; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_ASSERT_SCOPE_H_ diff --git a/deps/v8/src/ast-expression-visitor.cc b/deps/v8/src/ast-expression-visitor.cc index 782d4bbca6405d..e38b444699bb01 100644 --- a/deps/v8/src/ast-expression-visitor.cc +++ b/deps/v8/src/ast-expression-visitor.cc @@ -32,14 +32,20 @@ namespace internal { } while (false) -AstExpressionVisitor::AstExpressionVisitor(Isolate* isolate, Zone* zone, - FunctionLiteral* root) +AstExpressionVisitor::AstExpressionVisitor(Isolate* isolate, Expression* root) : root_(root), depth_(0) { - InitializeAstVisitor(isolate, zone); + InitializeAstVisitor(isolate); } -void AstExpressionVisitor::Run() { RECURSE(VisitFunctionLiteral(root_)); } +AstExpressionVisitor::AstExpressionVisitor(uintptr_t stack_limit, + Expression* root) + : root_(root), depth_(0) { + InitializeAstVisitor(stack_limit); +} + + +void AstExpressionVisitor::Run() { RECURSE(Visit(root_)); } void AstExpressionVisitor::VisitVariableDeclaration(VariableDeclaration* decl) { @@ -196,6 +202,12 @@ void AstExpressionVisitor::VisitNativeFunctionLiteral( NativeFunctionLiteral* expr) {} +void AstExpressionVisitor::VisitDoExpression(DoExpression* expr) { + RECURSE(VisitBlock(expr->block())); + RECURSE(VisitVariableProxy(expr->result())); +} + + void AstExpressionVisitor::VisitConditional(Conditional* expr) { RECURSE(Visit(expr->condition())); RECURSE(Visit(expr->then_expression())); @@ -223,6 +235,9 @@ void AstExpressionVisitor::VisitObjectLiteral(ObjectLiteral* expr) { ZoneList* props = expr->properties(); for (int i = 0; i < props->length(); ++i) { ObjectLiteralProperty* prop = props->at(i); + if (!prop->key()->IsLiteral()) { + RECURSE_EXPRESSION(Visit(prop->key())); + } RECURSE_EXPRESSION(Visit(prop->value())); } } @@ -336,21 +351,47 @@ void AstExpressionVisitor::VisitDeclarations(ZoneList* decls) { } -void AstExpressionVisitor::VisitClassLiteral(ClassLiteral* expr) {} +void AstExpressionVisitor::VisitClassLiteral(ClassLiteral* expr) { + VisitExpression(expr); + if (expr->extends() != nullptr) { + RECURSE_EXPRESSION(Visit(expr->extends())); + } + RECURSE_EXPRESSION(Visit(expr->constructor())); + ZoneList* props = expr->properties(); + for (int i = 0; i < props->length(); ++i) { + ObjectLiteralProperty* prop = props->at(i); + if (!prop->key()->IsLiteral()) { + RECURSE_EXPRESSION(Visit(prop->key())); + } + RECURSE_EXPRESSION(Visit(prop->value())); + } +} -void AstExpressionVisitor::VisitSpread(Spread* expr) {} +void AstExpressionVisitor::VisitSpread(Spread* expr) { + VisitExpression(expr); + RECURSE_EXPRESSION(Visit(expr->expression())); +} void AstExpressionVisitor::VisitEmptyParentheses(EmptyParentheses* expr) {} void AstExpressionVisitor::VisitSuperPropertyReference( - SuperPropertyReference* expr) {} + SuperPropertyReference* expr) { + VisitExpression(expr); + RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var())); + RECURSE_EXPRESSION(Visit(expr->home_object())); +} -void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) {} +void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) { + VisitExpression(expr); + RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var())); + RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var())); + RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var())); } -} // namespace v8::internal +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/ast-expression-visitor.h b/deps/v8/src/ast-expression-visitor.h index 43b34bac7968f9..a4bf34d63fe946 100644 --- a/deps/v8/src/ast-expression-visitor.h +++ b/deps/v8/src/ast-expression-visitor.h @@ -21,7 +21,8 @@ namespace internal { class AstExpressionVisitor : public AstVisitor { public: - AstExpressionVisitor(Isolate* isolate, Zone* zone, FunctionLiteral* root); + AstExpressionVisitor(Isolate* isolate, Expression* root); + AstExpressionVisitor(uintptr_t stack_limit, Expression* root); void Run(); protected: @@ -34,16 +35,16 @@ class AstExpressionVisitor : public AstVisitor { DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); -#define DECLARE_VISIT(type) virtual void Visit##type(type* node) override; +#define DECLARE_VISIT(type) void Visit##type(type* node) override; AST_NODE_LIST(DECLARE_VISIT) #undef DECLARE_VISIT - FunctionLiteral* root_; + Expression* root_; int depth_; DISALLOW_COPY_AND_ASSIGN(AstExpressionVisitor); }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_AST_EXPRESSION_VISITOR_H_ diff --git a/deps/v8/src/ast-literal-reindexer.cc b/deps/v8/src/ast-literal-reindexer.cc index e5729c7818a211..5987399f9742ce 100644 --- a/deps/v8/src/ast-literal-reindexer.cc +++ b/deps/v8/src/ast-literal-reindexer.cc @@ -43,6 +43,11 @@ void AstLiteralReindexer::VisitNativeFunctionLiteral( NativeFunctionLiteral* node) {} +void AstLiteralReindexer::VisitDoExpression(DoExpression* node) { + // TODO(caitp): literals in do expressions need re-indexing too. +} + + void AstLiteralReindexer::VisitLiteral(Literal* node) {} @@ -316,5 +321,5 @@ void AstLiteralReindexer::VisitFunctionLiteral(FunctionLiteral* node) { void AstLiteralReindexer::Reindex(Expression* pattern) { pattern->Accept(this); } -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/ast-literal-reindexer.h b/deps/v8/src/ast-literal-reindexer.h index 2fe920b7c46d30..14f64f6ef18a43 100644 --- a/deps/v8/src/ast-literal-reindexer.h +++ b/deps/v8/src/ast-literal-reindexer.h @@ -20,7 +20,7 @@ class AstLiteralReindexer final : public AstVisitor { int NextIndex() { return next_index_++; } private: -#define DEFINE_VISIT(type) virtual void Visit##type(type* node) override; +#define DEFINE_VISIT(type) void Visit##type(type* node) override; AST_NODE_LIST(DEFINE_VISIT) #undef DEFINE_VISIT @@ -39,7 +39,7 @@ class AstLiteralReindexer final : public AstVisitor { DISALLOW_COPY_AND_ASSIGN(AstLiteralReindexer); }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_AST_LITERAL_REINDEXER diff --git a/deps/v8/src/ast-numbering.cc b/deps/v8/src/ast-numbering.cc index 55eaacd1f5e3ce..8479191b5e9b44 100644 --- a/deps/v8/src/ast-numbering.cc +++ b/deps/v8/src/ast-numbering.cc @@ -14,18 +14,20 @@ class AstNumberingVisitor final : public AstVisitor { public: AstNumberingVisitor(Isolate* isolate, Zone* zone) : AstVisitor(), + isolate_(isolate), + zone_(zone), next_id_(BailoutId::FirstUsable().ToInt()), properties_(zone), - ic_slot_cache_(zone), + slot_cache_(zone), dont_optimize_reason_(kNoReason) { - InitializeAstVisitor(isolate, zone); + InitializeAstVisitor(isolate); } bool Renumber(FunctionLiteral* node); private: // AST node visitor interface. -#define DEFINE_VISIT(type) virtual void Visit##type(type* node) override; +#define DEFINE_VISIT(type) void Visit##type(type* node) override; AST_NODE_LIST(DEFINE_VISIT) #undef DEFINE_VISIT @@ -65,16 +67,18 @@ class AstNumberingVisitor final : public AstVisitor { template void ReserveFeedbackSlots(Node* node) { - node->AssignFeedbackVectorSlots(isolate(), properties_.get_spec(), - &ic_slot_cache_); + node->AssignFeedbackVectorSlots(isolate_, properties_.get_spec(), + &slot_cache_); } BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; } + Isolate* isolate_; + Zone* zone_; int next_id_; AstProperties properties_; - // The slot cache allows us to reuse certain vector IC slots. - ICSlotCache ic_slot_cache_; + // The slot cache allows us to reuse certain feedback vector slots. + FeedbackVectorSlotCache slot_cache_; BailoutReason dont_optimize_reason_; DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); @@ -132,6 +136,15 @@ void AstNumberingVisitor::VisitNativeFunctionLiteral( } +void AstNumberingVisitor::VisitDoExpression(DoExpression* node) { + IncrementNodeCount(); + DisableCrankshaft(kDoExpression); + node->set_base_id(ReserveIdRange(DoExpression::num_ids())); + Visit(node->block()); + Visit(node->result()); +} + + void AstNumberingVisitor::VisitLiteral(Literal* node) { IncrementNodeCount(); node->set_base_id(ReserveIdRange(Literal::num_ids())); @@ -466,11 +479,11 @@ void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) { for (int i = 0; i < node->properties()->length(); i++) { VisitObjectLiteralProperty(node->properties()->at(i)); } - node->BuildConstantProperties(isolate()); + node->BuildConstantProperties(isolate_); // Mark all computed expressions that are bound to a key that // is shadowed by a later occurrence of the same key. For the // marked expressions, no store code will be is emitted. - node->CalculateEmitStore(zone()); + node->CalculateEmitStore(zone_); ReserveFeedbackSlots(node); } @@ -489,6 +502,8 @@ void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) { for (int i = 0; i < node->values()->length(); i++) { Visit(node->values()->at(i)); } + node->BuildConstantElements(isolate_); + ReserveFeedbackSlots(node); } diff --git a/deps/v8/src/ast-value-factory.cc b/deps/v8/src/ast-value-factory.cc index fbcde8b45703fc..8a4a4daf0ce2b3 100644 --- a/deps/v8/src/ast-value-factory.cc +++ b/deps/v8/src/ast-value-factory.cc @@ -50,7 +50,7 @@ class OneByteStringStream { int pos_; }; -} +} // namespace class AstRawStringInternalizationKey : public HashTableKey { public: diff --git a/deps/v8/src/ast-value-factory.h b/deps/v8/src/ast-value-factory.h index 69fc6cc2f459c3..645b8b6631486c 100644 --- a/deps/v8/src/ast-value-factory.h +++ b/deps/v8/src/ast-value-factory.h @@ -255,6 +255,7 @@ class AstValue : public ZoneObject { F(dot_module, ".module") \ F(dot_result, ".result") \ F(dot_switch_tag, ".switch_tag") \ + F(dot_catch, ".catch") \ F(empty, "") \ F(eval, "eval") \ F(let, "let") \ @@ -366,7 +367,8 @@ class AstValueFactory { OTHER_CONSTANTS(F) #undef F }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #undef STRING_CONSTANTS #undef OTHER_CONSTANTS diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc index 3292b1d50bd333..b5c6cf57ea417c 100644 --- a/deps/v8/src/ast.cc +++ b/deps/v8/src/ast.cc @@ -71,7 +71,6 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, bit_field_(IsThisField::encode(var->is_this()) | IsAssignedField::encode(false) | IsResolvedField::encode(false)), - variable_feedback_slot_(FeedbackVectorICSlot::Invalid()), raw_name_(var->raw_name()), end_position_(end_position) { BindTo(var); @@ -85,7 +84,6 @@ VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bit_field_(IsThisField::encode(variable_kind == Variable::THIS) | IsAssignedField::encode(false) | IsResolvedField::encode(false)), - variable_feedback_slot_(FeedbackVectorICSlot::Invalid()), raw_name_(name), end_position_(end_position) {} @@ -100,14 +98,14 @@ void VariableProxy::BindTo(Variable* var) { void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) { + FeedbackVectorSlotCache* cache) { if (UsesVariableFeedbackSlot()) { // VariableProxies that point to the same Variable within a function can // make their loads from the same IC slot. if (var()->IsUnallocated()) { ZoneHashMap::Entry* entry = cache->Get(var()); if (entry != NULL) { - variable_feedback_slot_ = FeedbackVectorICSlot( + variable_feedback_slot_ = FeedbackVectorSlot( static_cast(reinterpret_cast(entry->value))); return; } @@ -121,7 +119,7 @@ void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate, static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec, - FeedbackVectorICSlot* out_slot) { + FeedbackVectorSlot* out_slot) { if (FLAG_vector_stores) { Property* property = expr->AsProperty(); LhsKind assign_type = Property::GetAssignType(property); @@ -138,9 +136,9 @@ static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec, } -void ForEachStatement::AssignFeedbackVectorSlots(Isolate* isolate, - FeedbackVectorSpec* spec, - ICSlotCache* cache) { +void ForEachStatement::AssignFeedbackVectorSlots( + Isolate* isolate, FeedbackVectorSpec* spec, + FeedbackVectorSlotCache* cache) { AssignVectorSlots(each(), spec, &each_slot_); } @@ -153,20 +151,19 @@ Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), target_(target), value_(value), - binary_operation_(NULL), - slot_(FeedbackVectorICSlot::Invalid()) {} + binary_operation_(NULL) {} void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) { + FeedbackVectorSlotCache* cache) { AssignVectorSlots(target(), spec, &slot_); } void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) { + FeedbackVectorSlotCache* cache) { AssignVectorSlots(expression(), spec, &slot_); } @@ -227,7 +224,6 @@ ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value, bool is_computed_name) : key_(key), value_(value), - slot_(FeedbackVectorICSlot::Invalid()), kind_(kind), emit_store_(true), is_static_(is_static), @@ -240,7 +236,6 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, bool is_computed_name) : key_(key), value_(value), - slot_(FeedbackVectorICSlot::Invalid()), emit_store_(true), is_static_(is_static), is_computed_name_(is_computed_name) { @@ -260,7 +255,7 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) { + FeedbackVectorSlotCache* cache) { if (!FLAG_vector_stores) return; // This logic that computes the number of slots needed for vector store @@ -273,7 +268,7 @@ void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate, ObjectLiteral::Property* property = properties()->at(i); Expression* value = property->value(); if (FunctionLiteral::NeedsHomeObject(value)) { - property->set_slot(spec->AddStoreICSlot()); + property->SetSlot(spec->AddStoreICSlot()); } } } @@ -298,7 +293,7 @@ bool ObjectLiteral::Property::emit_store() { void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) { + FeedbackVectorSlotCache* cache) { if (!FLAG_vector_stores) return; // This logic that computes the number of slots needed for vector store @@ -321,27 +316,27 @@ void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate, // contains computed properties with an uninitialized value. if (key->value()->IsInternalizedString()) { if (property->emit_store()) { - property->set_slot(spec->AddStoreICSlot()); + property->SetSlot(spec->AddStoreICSlot()); if (FunctionLiteral::NeedsHomeObject(value)) { - spec->AddStoreICSlot(); + property->SetSlot(spec->AddStoreICSlot(), 1); } } break; } if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { - property->set_slot(spec->AddStoreICSlot()); + property->SetSlot(spec->AddStoreICSlot()); } break; case ObjectLiteral::Property::PROTOTYPE: break; case ObjectLiteral::Property::GETTER: if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { - property->set_slot(spec->AddStoreICSlot()); + property->SetSlot(spec->AddStoreICSlot()); } break; case ObjectLiteral::Property::SETTER: if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { - property->set_slot(spec->AddStoreICSlot()); + property->SetSlot(spec->AddStoreICSlot()); } break; } @@ -353,7 +348,7 @@ void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate, Expression* value = property->value(); if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { if (FunctionLiteral::NeedsHomeObject(value)) { - property->set_slot(spec->AddStoreICSlot()); + property->SetSlot(spec->AddStoreICSlot()); } } } @@ -552,6 +547,27 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) { } +void ArrayLiteral::AssignFeedbackVectorSlots(Isolate* isolate, + FeedbackVectorSpec* spec, + FeedbackVectorSlotCache* cache) { + if (!FLAG_vector_stores) return; + + // This logic that computes the number of slots needed for vector store + // ics must mirror FullCodeGenerator::VisitArrayLiteral. + int array_index = 0; + for (; array_index < values()->length(); array_index++) { + Expression* subexpr = values()->at(array_index); + if (subexpr->IsSpread()) break; + if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; + + // We'll reuse the same literal slot for all of the non-constant + // subexpressions that use a keyed store IC. + literal_slot_ = spec->AddKeyedStoreICSlot(); + return; + } +} + + Handle MaterializedLiteral::GetBoilerplateValue(Expression* expression, Isolate* isolate) { if (expression->IsLiteral()) { @@ -720,12 +736,12 @@ bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const { void Call::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) { + FeedbackVectorSlotCache* cache) { if (IsUsingCallFeedbackICSlot(isolate)) { ic_slot_ = spec->AddCallICSlot(); } if (IsUsingCallFeedbackSlot(isolate)) { - slot_ = spec->AddStubSlot(); + stub_slot_ = spec->AddGeneralSlot(); } } @@ -745,7 +761,16 @@ Call::CallType Call::GetCallType(Isolate* isolate) const { if (expression()->IsSuperCallReference()) return SUPER_CALL; Property* property = expression()->AsProperty(); - return property != NULL ? PROPERTY_CALL : OTHER_CALL; + if (property != nullptr) { + bool is_super = property->IsSuperAccess(); + if (property->key()->IsPropertyName()) { + return is_super ? NAMED_SUPER_PROPERTY_CALL : NAMED_PROPERTY_CALL; + } else { + return is_super ? KEYED_SUPER_PROPERTY_CALL : KEYED_PROPERTY_CALL; + } + } + + return OTHER_CALL; } @@ -917,8 +942,7 @@ class RegExpUnparser final : public RegExpVisitor { public: RegExpUnparser(std::ostream& os, Zone* zone) : os_(os), zone_(zone) {} void VisitCharacterRange(CharacterRange that); -#define MAKE_CASE(Name) \ - virtual void* Visit##Name(RegExp##Name*, void* data) override; +#define MAKE_CASE(Name) void* Visit##Name(RegExp##Name*, void* data) override; FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) #undef MAKE_CASE private: diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h index 4764918849dfe2..14f71a6cc28bfb 100644 --- a/deps/v8/src/ast.h +++ b/deps/v8/src/ast.h @@ -90,7 +90,8 @@ namespace internal { V(SuperPropertyReference) \ V(SuperCallReference) \ V(CaseClause) \ - V(EmptyParentheses) + V(EmptyParentheses) \ + V(DoExpression) #define AST_NODE_LIST(V) \ DECLARATION_NODE_LIST(V) \ @@ -138,14 +139,14 @@ typedef ZoneList> ZoneObjectList; friend class AstNodeFactory; -class ICSlotCache { +class FeedbackVectorSlotCache { public: - explicit ICSlotCache(Zone* zone) + explicit FeedbackVectorSlotCache(Zone* zone) : zone_(zone), hash_map_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity, ZoneAllocationPolicy(zone)) {} - void Put(Variable* variable, FeedbackVectorICSlot slot) { + void Put(Variable* variable, FeedbackVectorSlot slot) { ZoneHashMap::Entry* entry = hash_map_.LookupOrInsert( variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_)); entry->value = reinterpret_cast(slot.ToInt()); @@ -230,7 +231,7 @@ class AstNode: public ZoneObject { // vtable entry per node, something we don't want for space reasons. virtual void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) {} + FeedbackVectorSlotCache* cache) {} private: // Hidden to prevent accidental usage. It would have to load the @@ -458,10 +459,6 @@ class Block final : public BreakableStatement { public: DECLARE_NODE_TYPE(Block) - void AddStatement(Statement* statement, Zone* zone) { - statements_.Add(statement, zone); - } - ZoneList* statements() { return &statements_; } bool ignore_completion_value() const { return ignore_completion_value_; } @@ -494,6 +491,29 @@ class Block final : public BreakableStatement { }; +class DoExpression final : public Expression { + public: + DECLARE_NODE_TYPE(DoExpression) + + Block* block() { return block_; } + VariableProxy* result() { return result_; } + + protected: + DoExpression(Zone* zone, Block* block, VariableProxy* result, int pos) + : Expression(zone, pos), block_(block), result_(result) { + DCHECK_NOT_NULL(block_); + DCHECK_NOT_NULL(result_); + } + static int parent_num_ids() { return Expression::num_ids(); } + + private: + int local_id(int n) const { return base_id() + parent_num_ids() + n; } + + Block* block_; + VariableProxy* result_; +}; + + class Declaration : public AstNode { public: VariableProxy* proxy() const { return proxy_; } @@ -640,6 +660,7 @@ class IterationStatement : public BreakableStatement { IterationStatement* AsIterationStatement() final { return this; } Statement* body() const { return body_; } + void set_body(Statement* s) { body_ = s; } static int num_ids() { return parent_num_ids() + 1; } BailoutId OsrEntryId() const { return BailoutId(local_id(0)); } @@ -777,20 +798,17 @@ class ForEachStatement : public IterationStatement { Expression* subject() const { return subject_; } void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; - FeedbackVectorICSlot EachFeedbackSlot() const { return each_slot_; } + FeedbackVectorSlotCache* cache) override; + FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; } protected: ForEachStatement(Zone* zone, ZoneList* labels, int pos) - : IterationStatement(zone, labels, pos), - each_(NULL), - subject_(NULL), - each_slot_(FeedbackVectorICSlot::Invalid()) {} + : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {} private: Expression* each_; Expression* subject_; - FeedbackVectorICSlot each_slot_; + FeedbackVectorSlot each_slot_; }; @@ -804,9 +822,9 @@ class ForInStatement final : public ForEachStatement { // Type feedback information. void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override { + FeedbackVectorSlotCache* cache) override { ForEachStatement::AssignFeedbackVectorSlots(isolate, spec, cache); - for_in_feedback_slot_ = spec->AddStubSlot(); + for_in_feedback_slot_ = spec->AddGeneralSlot(); } FeedbackVectorSlot ForInFeedbackSlot() { @@ -830,9 +848,7 @@ class ForInStatement final : public ForEachStatement { protected: ForInStatement(Zone* zone, ZoneList* labels, int pos) - : ForEachStatement(zone, labels, pos), - for_in_type_(SLOW_FOR_IN), - for_in_feedback_slot_(FeedbackVectorSlot::Invalid()) {} + : ForEachStatement(zone, labels, pos), for_in_type_(SLOW_FOR_IN) {} static int parent_num_ids() { return ForEachStatement::num_ids(); } private: @@ -988,6 +1004,7 @@ class WithStatement final : public Statement { Scope* scope() { return scope_; } Expression* expression() const { return expression_; } Statement* statement() const { return statement_; } + void set_statement(Statement* s) { statement_ = s; } void set_base_id(int id) { base_id_ = id; } static int num_ids() { return parent_num_ids() + 1; } @@ -1092,6 +1109,9 @@ class IfStatement final : public Statement { Statement* then_statement() const { return then_statement_; } Statement* else_statement() const { return else_statement_; } + void set_then_statement(Statement* s) { then_statement_ = s; } + void set_else_statement(Statement* s) { else_statement_ = s; } + bool IsJump() const override { return HasThenStatement() && then_statement()->IsJump() && HasElseStatement() && else_statement()->IsJump(); @@ -1131,6 +1151,7 @@ class IfStatement final : public Statement { class TryStatement : public Statement { public: Block* try_block() const { return try_block_; } + void set_try_block(Block* b) { try_block_ = b; } void set_base_id(int id) { base_id_ = id; } static int num_ids() { return parent_num_ids() + 1; } @@ -1163,6 +1184,7 @@ class TryCatchStatement final : public TryStatement { Scope* scope() { return scope_; } Variable* variable() { return variable_; } Block* catch_block() const { return catch_block_; } + void set_catch_block(Block* b) { catch_block_ = b; } protected: TryCatchStatement(Zone* zone, Block* try_block, Scope* scope, @@ -1184,6 +1206,7 @@ class TryFinallyStatement final : public TryStatement { DECLARE_NODE_TYPE(TryFinallyStatement) Block* finally_block() const { return finally_block_; } + void set_finally_block(Block* b) { finally_block_ = b; } protected: TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block, @@ -1301,7 +1324,7 @@ class AstLiteralReindexer; // Base class for literals that needs space in the corresponding JSFunction. class MaterializedLiteral : public Expression { public: - virtual MaterializedLiteral* AsMaterializedLiteral() { return this; } + MaterializedLiteral* AsMaterializedLiteral() final { return this; } int literal_index() { return literal_index_; } @@ -1383,13 +1406,14 @@ class ObjectLiteralProperty final : public ZoneObject { bool is_static() const { return is_static_; } bool is_computed_name() const { return is_computed_name_; } - FeedbackVectorICSlot GetSlot(int offset = 0) const { - if (slot_.IsInvalid()) return slot_; - int slot = slot_.ToInt(); - return FeedbackVectorICSlot(slot + offset); + FeedbackVectorSlot GetSlot(int offset = 0) const { + DCHECK_LT(offset, static_cast(arraysize(slots_))); + return slots_[offset]; + } + void SetSlot(FeedbackVectorSlot slot, int offset = 0) { + DCHECK_LT(offset, static_cast(arraysize(slots_))); + slots_[offset] = slot; } - FeedbackVectorICSlot slot() const { return slot_; } - void set_slot(FeedbackVectorICSlot slot) { slot_ = slot; } void set_receiver_type(Handle map) { receiver_type_ = map; } @@ -1405,7 +1429,7 @@ class ObjectLiteralProperty final : public ZoneObject { private: Expression* key_; Expression* value_; - FeedbackVectorICSlot slot_; + FeedbackVectorSlot slots_[2]; Kind kind_; bool emit_store_; bool is_static_; @@ -1486,7 +1510,7 @@ class ObjectLiteral final : public MaterializedLiteral { // Object literals need one feedback slot for each non-trivial value, as well // as some slots for home objects. void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; + FeedbackVectorSlotCache* cache) override; protected: ObjectLiteral(Zone* zone, ZoneList* properties, int literal_index, @@ -1498,9 +1522,7 @@ class ObjectLiteral final : public MaterializedLiteral { fast_elements_(false), has_elements_(false), may_store_doubles_(false), - has_function_(has_function), - slot_(FeedbackVectorICSlot::Invalid()) { - } + has_function_(has_function) {} static int parent_num_ids() { return MaterializedLiteral::num_ids(); } private: @@ -1512,7 +1534,28 @@ class ObjectLiteral final : public MaterializedLiteral { bool has_elements_; bool may_store_doubles_; bool has_function_; - FeedbackVectorICSlot slot_; + FeedbackVectorSlot slot_; +}; + + +// A map from property names to getter/setter pairs allocated in the zone. +class AccessorTable : public TemplateHashMap { + public: + explicit AccessorTable(Zone* zone) + : TemplateHashMap(Literal::Match, + ZoneAllocationPolicy(zone)), + zone_(zone) {} + + Iterator lookup(Literal* literal) { + Iterator it = find(literal, true, ZoneAllocationPolicy(zone_)); + if (it->second == NULL) it->second = new (zone_) ObjectLiteral::Accessors(); + return it; + } + + private: + Zone* zone_; }; @@ -1586,6 +1629,10 @@ class ArrayLiteral final : public MaterializedLiteral { kIsStrong = 1 << 2 }; + void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, + FeedbackVectorSlotCache* cache) override; + FeedbackVectorSlot LiteralFeedbackSlot() const { return literal_slot_; } + protected: ArrayLiteral(Zone* zone, ZoneList* values, int first_spread_index, int literal_index, bool is_strong, @@ -1601,6 +1648,7 @@ class ArrayLiteral final : public MaterializedLiteral { Handle constant_elements_; ZoneList* values_; int first_spread_index_; + FeedbackVectorSlot literal_slot_; }; @@ -1656,11 +1704,9 @@ class VariableProxy final : public Expression { } void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; + FeedbackVectorSlotCache* cache) override; - FeedbackVectorICSlot VariableFeedbackSlot() { - return variable_feedback_slot_; - } + FeedbackVectorSlot VariableFeedbackSlot() { return variable_feedback_slot_; } static int num_ids() { return parent_num_ids() + 1; } BailoutId BeforeId() const { return BailoutId(local_id(0)); } @@ -1683,7 +1729,7 @@ class VariableProxy final : public Expression { // Start with 16-bit (or smaller) field, which should get packed together // with Expression's trailing 16-bit field. uint8_t bit_field_; - FeedbackVectorICSlot variable_feedback_slot_; + FeedbackVectorSlot variable_feedback_slot_; union { const AstRawString* raw_name_; // if !is_resolved_ Variable* var_; // if is_resolved_ @@ -1755,14 +1801,14 @@ class Property final : public Expression { bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); } void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override { + FeedbackVectorSlotCache* cache) override { FeedbackVectorSlotKind kind = key()->IsPropertyName() ? FeedbackVectorSlotKind::LOAD_IC : FeedbackVectorSlotKind::KEYED_LOAD_IC; property_feedback_slot_ = spec->AddSlot(kind); } - FeedbackVectorICSlot PropertyFeedbackSlot() const { + FeedbackVectorSlot PropertyFeedbackSlot() const { return property_feedback_slot_; } @@ -1780,7 +1826,6 @@ class Property final : public Expression { bit_field_(IsForCallField::encode(false) | IsStringAccessField::encode(false) | InlineCacheStateField::encode(UNINITIALIZED)), - property_feedback_slot_(FeedbackVectorICSlot::Invalid()), obj_(obj), key_(key) {} static int parent_num_ids() { return Expression::num_ids(); } @@ -1793,7 +1838,7 @@ class Property final : public Expression { class KeyTypeField : public BitField8 {}; class InlineCacheStateField : public BitField8 {}; uint8_t bit_field_; - FeedbackVectorICSlot property_feedback_slot_; + FeedbackVectorSlot property_feedback_slot_; Expression* obj_; Expression* key_; SmallMapList receiver_types_; @@ -1809,11 +1854,11 @@ class Call final : public Expression { // Type feedback information. void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; + FeedbackVectorSlotCache* cache) override; - FeedbackVectorSlot CallFeedbackSlot() const { return slot_; } + FeedbackVectorSlot CallFeedbackSlot() const { return stub_slot_; } - FeedbackVectorICSlot CallFeedbackICSlot() const { return ic_slot_; } + FeedbackVectorSlot CallFeedbackICSlot() const { return ic_slot_; } SmallMapList* GetReceiverTypes() override { if (expression()->IsProperty()) { @@ -1851,10 +1896,11 @@ class Call final : public Expression { allocation_site_ = site; } - static int num_ids() { return parent_num_ids() + 3; } + static int num_ids() { return parent_num_ids() + 4; } BailoutId ReturnId() const { return BailoutId(local_id(0)); } BailoutId EvalId() const { return BailoutId(local_id(1)); } BailoutId LookupId() const { return BailoutId(local_id(2)); } + BailoutId CallId() const { return BailoutId(local_id(3)); } bool is_uninitialized() const { return IsUninitializedField::decode(bit_field_); @@ -1867,7 +1913,10 @@ class Call final : public Expression { POSSIBLY_EVAL_CALL, GLOBAL_CALL, LOOKUP_SLOT_CALL, - PROPERTY_CALL, + NAMED_PROPERTY_CALL, + KEYED_PROPERTY_CALL, + NAMED_SUPER_PROPERTY_CALL, + KEYED_SUPER_PROPERTY_CALL, SUPER_CALL, OTHER_CALL }; @@ -1886,8 +1935,6 @@ class Call final : public Expression { Call(Zone* zone, Expression* expression, ZoneList* arguments, int pos) : Expression(zone, pos), - ic_slot_(FeedbackVectorICSlot::Invalid()), - slot_(FeedbackVectorSlot::Invalid()), expression_(expression), arguments_(arguments), bit_field_(IsUninitializedField::encode(false)) { @@ -1900,8 +1947,8 @@ class Call final : public Expression { private: int local_id(int n) const { return base_id() + parent_num_ids() + n; } - FeedbackVectorICSlot ic_slot_; - FeedbackVectorSlot slot_; + FeedbackVectorSlot ic_slot_; + FeedbackVectorSlot stub_slot_; Expression* expression_; ZoneList* arguments_; Handle target_; @@ -1920,8 +1967,8 @@ class CallNew final : public Expression { // Type feedback information. void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override { - callnew_feedback_slot_ = spec->AddStubSlot(); + FeedbackVectorSlotCache* cache) override { + callnew_feedback_slot_ = spec->AddGeneralSlot(); } FeedbackVectorSlot CallNewFeedbackSlot() { @@ -1955,8 +2002,7 @@ class CallNew final : public Expression { : Expression(zone, pos), expression_(expression), arguments_(arguments), - is_monomorphic_(false), - callnew_feedback_slot_(FeedbackVectorSlot::Invalid()) {} + is_monomorphic_(false) {} static int parent_num_ids() { return Expression::num_ids(); } @@ -2035,7 +2081,7 @@ class UnaryOperation final : public Expression { BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); } BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); } - virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) override; + void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) override; protected: UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos) @@ -2080,7 +2126,7 @@ class BinaryOperation final : public Expression { if (arg.IsJust()) fixed_right_arg_value_ = arg.FromJust(); } - virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) override; + void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) override; protected: BinaryOperation(Zone* zone, Token::Value op, Expression* left, @@ -2151,8 +2197,8 @@ class CountOperation final : public Expression { } void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; - FeedbackVectorICSlot CountSlot() const { return slot_; } + FeedbackVectorSlotCache* cache) override; + FeedbackVectorSlot CountSlot() const { return slot_; } protected: CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr, @@ -2162,8 +2208,7 @@ class CountOperation final : public Expression { IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) | StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), type_(NULL), - expression_(expr), - slot_(FeedbackVectorICSlot::Invalid()) {} + expression_(expr) {} static int parent_num_ids() { return Expression::num_ids(); } private: @@ -2180,7 +2225,7 @@ class CountOperation final : public Expression { Type* type_; Expression* expression_; SmallMapList receiver_types_; - FeedbackVectorICSlot slot_; + FeedbackVectorSlot slot_; }; @@ -2324,8 +2369,8 @@ class Assignment final : public Expression { } void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; - FeedbackVectorICSlot AssignmentSlot() const { return slot_; } + FeedbackVectorSlotCache* cache) override; + FeedbackVectorSlot AssignmentSlot() const { return slot_; } protected: Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value, @@ -2347,7 +2392,7 @@ class Assignment final : public Expression { Expression* value_; BinaryOperation* binary_operation_; SmallMapList receiver_types_; - FeedbackVectorICSlot slot_; + FeedbackVectorSlot slot_; }; @@ -2369,23 +2414,22 @@ class Yield final : public Expression { // Type feedback information. bool HasFeedbackSlots() const { return yield_kind() == kDelegating; } void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override { + FeedbackVectorSlotCache* cache) override { if (HasFeedbackSlots()) { yield_first_feedback_slot_ = spec->AddKeyedLoadICSlot(); - spec->AddLoadICSlots(2); + keyed_load_feedback_slot_ = spec->AddLoadICSlot(); + done_feedback_slot_ = spec->AddLoadICSlot(); } } - FeedbackVectorICSlot KeyedLoadFeedbackSlot() { + FeedbackVectorSlot KeyedLoadFeedbackSlot() { DCHECK(!HasFeedbackSlots() || !yield_first_feedback_slot_.IsInvalid()); return yield_first_feedback_slot_; } - FeedbackVectorICSlot DoneFeedbackSlot() { - return KeyedLoadFeedbackSlot().next(); - } + FeedbackVectorSlot DoneFeedbackSlot() { return keyed_load_feedback_slot_; } - FeedbackVectorICSlot ValueFeedbackSlot() { return DoneFeedbackSlot().next(); } + FeedbackVectorSlot ValueFeedbackSlot() { return done_feedback_slot_; } protected: Yield(Zone* zone, Expression* generator_object, Expression* expression, @@ -2393,14 +2437,15 @@ class Yield final : public Expression { : Expression(zone, pos), generator_object_(generator_object), expression_(expression), - yield_kind_(yield_kind), - yield_first_feedback_slot_(FeedbackVectorICSlot::Invalid()) {} + yield_kind_(yield_kind) {} private: Expression* generator_object_; Expression* expression_; Kind yield_kind_; - FeedbackVectorICSlot yield_first_feedback_slot_; + FeedbackVectorSlot yield_first_feedback_slot_; + FeedbackVectorSlot keyed_load_feedback_slot_; + FeedbackVectorSlot done_feedback_slot_; }; @@ -2642,14 +2687,14 @@ class ClassLiteral final : public Expression { // Object literals need one feedback slot for each non-trivial value, as well // as some slots for home objects. void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - ICSlotCache* cache) override; + FeedbackVectorSlotCache* cache) override; bool NeedsProxySlot() const { - return FLAG_vector_stores && scope() != NULL && + return FLAG_vector_stores && class_variable_proxy() != nullptr && class_variable_proxy()->var()->IsUnallocated(); } - FeedbackVectorICSlot ProxySlot() const { return slot_; } + FeedbackVectorSlot ProxySlot() const { return slot_; } protected: ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope, @@ -2663,9 +2708,7 @@ class ClassLiteral final : public Expression { extends_(extends), constructor_(constructor), properties_(properties), - end_position_(end_position), - slot_(FeedbackVectorICSlot::Invalid()) { - } + end_position_(end_position) {} static int parent_num_ids() { return Expression::num_ids(); } @@ -2679,7 +2722,7 @@ class ClassLiteral final : public Expression { FunctionLiteral* constructor_; ZoneList* properties_; int end_position_; - FeedbackVectorICSlot slot_; + FeedbackVectorSlot slot_; }; @@ -2816,8 +2859,7 @@ class RegExpDisjunction final : public RegExpTree { public: explicit RegExpDisjunction(ZoneList* alternatives); void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpDisjunction* AsDisjunction() override; Interval CaptureRegisters() override; bool IsDisjunction() override; @@ -2840,8 +2882,7 @@ class RegExpAlternative final : public RegExpTree { public: explicit RegExpAlternative(ZoneList* nodes); void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpAlternative* AsAlternative() override; Interval CaptureRegisters() override; bool IsAlternative() override; @@ -2869,8 +2910,7 @@ class RegExpAssertion final : public RegExpTree { }; explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpAssertion* AsAssertion() override; bool IsAssertion() override; bool IsAnchoredAtStart() override; @@ -2915,8 +2955,7 @@ class RegExpCharacterClass final : public RegExpTree { : set_(type), is_negated_(false) { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpCharacterClass* AsCharacterClass() override; bool IsCharacterClass() override; bool IsTextElement() override { return true; } @@ -2952,8 +2991,7 @@ class RegExpAtom final : public RegExpTree { public: explicit RegExpAtom(Vector data) : data_(data) { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpAtom* AsAtom() override; bool IsAtom() override; bool IsTextElement() override { return true; } @@ -2971,8 +3009,7 @@ class RegExpText final : public RegExpTree { public: explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {} void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpText* AsText() override; bool IsText() override; bool IsTextElement() override { return true; } @@ -3006,8 +3043,7 @@ class RegExpQuantifier final : public RegExpTree { } } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; static RegExpNode* ToNode(int min, int max, bool is_greedy, @@ -3042,8 +3078,7 @@ class RegExpCapture final : public RegExpTree { explicit RegExpCapture(RegExpTree* body, int index) : body_(body), index_(index) { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; static RegExpNode* ToNode(RegExpTree* body, int index, RegExpCompiler* compiler, @@ -3078,8 +3113,7 @@ class RegExpLookahead final : public RegExpTree { capture_from_(capture_from) { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpLookahead* AsLookahead() override; Interval CaptureRegisters() override; bool IsLookahead() override; @@ -3104,8 +3138,7 @@ class RegExpBackReference final : public RegExpTree { explicit RegExpBackReference(RegExpCapture* capture) : capture_(capture) { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpBackReference* AsBackReference() override; bool IsBackReference() override; int min_match() override { return 0; } @@ -3121,8 +3154,7 @@ class RegExpEmpty final : public RegExpTree { public: RegExpEmpty() { } void* Accept(RegExpVisitor* visitor, void* data) override; - virtual RegExpNode* ToNode(RegExpCompiler* compiler, - RegExpNode* on_success) override; + RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; RegExpEmpty* AsEmpty() override; bool IsEmpty() override; int min_match() override { return 0; } @@ -3167,23 +3199,25 @@ class AstVisitor BASE_EMBEDDED { \ bool CheckStackOverflow() { \ if (stack_overflow_) return true; \ - StackLimitCheck check(isolate_); \ - if (!check.HasOverflowed()) return false; \ - stack_overflow_ = true; \ - return true; \ + if (GetCurrentStackPosition() < stack_limit_) { \ + stack_overflow_ = true; \ + return true; \ + } \ + return false; \ } \ \ private: \ - void InitializeAstVisitor(Isolate* isolate, Zone* zone) { \ - isolate_ = isolate; \ - zone_ = zone; \ + void InitializeAstVisitor(Isolate* isolate) { \ + stack_limit_ = isolate->stack_guard()->real_climit(); \ + stack_overflow_ = false; \ + } \ + \ + void InitializeAstVisitor(uintptr_t stack_limit) { \ + stack_limit_ = stack_limit; \ stack_overflow_ = false; \ } \ - Zone* zone() { return zone_; } \ - Isolate* isolate() { return isolate_; } \ \ - Isolate* isolate_; \ - Zone* zone_; \ + uintptr_t stack_limit_; \ bool stack_overflow_ @@ -3197,6 +3231,8 @@ class AstNodeFactory final BASE_EMBEDDED { parser_zone_(ast_value_factory->zone()), ast_value_factory_(ast_value_factory) {} + AstValueFactory* ast_value_factory() const { return ast_value_factory_; } + VariableDeclaration* NewVariableDeclaration( VariableProxy* proxy, VariableMode mode, Scope* scope, int pos, bool is_class_declaration = false, int declaration_group_start = -1) { @@ -3567,6 +3603,11 @@ class AstNodeFactory final BASE_EMBEDDED { NativeFunctionLiteral(parser_zone_, name, extension, pos); } + DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) { + VariableProxy* result = NewVariableProxy(result_var, pos); + return new (parser_zone_) DoExpression(parser_zone_, block, result, pos); + } + ThisFunction* NewThisFunction(int pos) { return new (local_zone_) ThisFunction(local_zone_, pos); } @@ -3622,6 +3663,7 @@ class AstNodeFactory final BASE_EMBEDDED { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_AST_H_ diff --git a/deps/v8/src/background-parsing-task.h b/deps/v8/src/background-parsing-task.h index e99916169cfc81..c224303e051cda 100644 --- a/deps/v8/src/background-parsing-task.h +++ b/deps/v8/src/background-parsing-task.h @@ -54,7 +54,7 @@ class BackgroundParsingTask : public ScriptCompiler::ScriptStreamingTask { StreamedSource* source_; // Not owned. int stack_size_; }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_BACKGROUND_PARSING_TASK_H_ diff --git a/deps/v8/src/bailout-reason.h b/deps/v8/src/bailout-reason.h index b63c5fbfba92d2..c09e429cd843d8 100644 --- a/deps/v8/src/bailout-reason.h +++ b/deps/v8/src/bailout-reason.h @@ -29,7 +29,6 @@ namespace internal { "Assignment to parameter, function uses arguments object") \ V(kAssignmentToParameterInArgumentsObject, \ "Assignment to parameter in arguments object") \ - V(kAttemptToUseUndefinedCache, "Attempt to use undefined cache") \ V(kBadValueContextForArgumentsObjectValue, \ "Bad value context for arguments object value") \ V(kBadValueContextForArgumentsValue, \ @@ -58,6 +57,7 @@ namespace internal { V(kDestinationOfCopyNotAligned, "Destination of copy not aligned") \ V(kDontDeleteCellsCannotContainTheHole, \ "DontDelete cells can't contain the hole") \ + V(kDoExpression, "Do expression encountered") \ V(kDoPushArgumentNotImplementedForDoubleType, \ "DoPushArgument not implemented for double type") \ V(kEliminatedBoundsCheckFailed, "Eliminated bounds check failed") \ @@ -105,14 +105,6 @@ namespace internal { V(kInputGPRIsExpectedToHaveUpper32Cleared, \ "Input GPR is expected to have upper32 cleared") \ V(kInputStringTooLong, "Input string too long") \ - V(kInstanceofStubUnexpectedCallSiteCacheCheck, \ - "InstanceofStub unexpected call site cache (check)") \ - V(kInstanceofStubUnexpectedCallSiteCacheCmp1, \ - "InstanceofStub unexpected call site cache (cmp 1)") \ - V(kInstanceofStubUnexpectedCallSiteCacheCmp2, \ - "InstanceofStub unexpected call site cache (cmp 2)") \ - V(kInstanceofStubUnexpectedCallSiteCacheMov, \ - "InstanceofStub unexpected call site cache (mov)") \ V(kInteger32ToSmiFieldWritingToNonSmiLocation, \ "Integer32ToSmiField writing to non-smi location") \ V(kInvalidCaptureReferenced, "Invalid capture referenced") \ @@ -183,7 +175,8 @@ namespace internal { V(kRegisterWasClobbered, "Register was clobbered") \ V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \ V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \ - V(kScriptContext, "Allocation of script context") \ + V(kSloppyFunctionExpectsJSReceiverReceiver, \ + "Sloppy function expects JSReceiver as receiver.") \ V(kSmiAdditionOverflow, "Smi addition overflow") \ V(kSmiSubtractionOverflow, "Smi subtraction overflow") \ V(kSpread, "Spread in array literal") \ @@ -192,20 +185,6 @@ namespace internal { V(kSuperReference, "Super reference") \ V(kTheCurrentStackPointerIsBelowCsp, \ "The current stack pointer is below csp") \ - V(kTheInstructionShouldBeALis, "The instruction should be a lis") \ - V(kTheInstructionShouldBeALui, "The instruction should be a lui") \ - V(kTheInstructionShouldBeAnOri, "The instruction should be an ori") \ - V(kTheInstructionShouldBeAnOris, "The instruction should be an oris") \ - V(kTheInstructionShouldBeALi, "The instruction should be a li") \ - V(kTheInstructionShouldBeASldi, "The instruction should be a sldi") \ - V(kTheInstructionToPatchShouldBeAnLdrLiteral, \ - "The instruction to patch should be a ldr literal") \ - V(kTheInstructionToPatchShouldBeALis, \ - "The instruction to patch should be a lis") \ - V(kTheInstructionToPatchShouldBeALui, \ - "The instruction to patch should be a lui") \ - V(kTheInstructionToPatchShouldBeAnOri, \ - "The instruction to patch should be an ori") \ V(kTheSourceAndDestinationAreTheSame, \ "The source and destination are the same") \ V(kTheStackWasCorruptedByMacroAssemblerCall, \ @@ -220,7 +199,6 @@ namespace internal { "ToOperand Unsupported double immediate") \ V(kTryCatchStatement, "TryCatchStatement") \ V(kTryFinallyStatement, "TryFinallyStatement") \ - V(kUnableToEncodeValueAsSmi, "Unable to encode value as smi") \ V(kUnalignedAllocationInNewSpace, "Unaligned allocation in new space") \ V(kUnalignedCellInWriteBarrier, "Unaligned cell in write barrier") \ V(kUnexpectedAllocationTop, "Unexpected allocation top") \ @@ -254,15 +232,11 @@ namespace internal { "Unexpected number of pre-allocated property fields") \ V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \ V(kUnexpectedSmi, "Unexpected smi value") \ - V(kUnexpectedStringFunction, "Unexpected String function") \ + V(kUnexpectedStackPointer, "The stack pointer is not the expected value") \ V(kUnexpectedStringType, "Unexpected string type") \ - V(kUnexpectedStringWrapperInstanceSize, \ - "Unexpected string wrapper instance size") \ V(kUnexpectedTypeForRegExpDataFixedArrayExpected, \ "Unexpected type for RegExp data, FixedArray expected") \ V(kUnexpectedValue, "Unexpected value") \ - V(kUnexpectedUnusedPropertiesOfStringWrapper, \ - "Unexpected unused properties of string wrapper") \ V(kUnsupportedConstCompoundAssignment, \ "Unsupported const compound assignment") \ V(kUnsupportedCountOperationWithConst, \ @@ -275,6 +249,7 @@ namespace internal { V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments") \ V(kUnsupportedPhiUseOfConstVariable, \ "Unsupported phi use of const variable") \ + V(kUnexpectedReturnFromThrow, "Unexpectedly returned from a throw") \ V(kUnsupportedTaggedImmediate, "Unsupported tagged immediate") \ V(kVariableResolvedToWithContext, "Variable resolved to with context") \ V(kWeShouldNotHaveAnEmptyLexicalContext, \ diff --git a/deps/v8/src/base.isolate b/deps/v8/src/base.isolate index dceb4133399c6a..097b914399c64d 100644 --- a/deps/v8/src/base.isolate +++ b/deps/v8/src/base.isolate @@ -2,8 +2,19 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. { + 'includes': [ + '../third_party/icu/icu.isolate', + '../build/config/win/msvs_dependencies.isolate', + ], 'conditions': [ - ['v8_use_external_startup_data==1', { + ['use_custom_libcxx==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/lib/libc++.so', + ], + }, + }], + ['v8_use_snapshot=="true" and v8_use_external_startup_data==1', { 'variables': { 'files': [ '<(PRODUCT_DIR)/natives_blob.bin', @@ -11,5 +22,38 @@ ], }, }], + ['OS=="linux" and component=="shared_library" and target_arch=="ia32"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/lib/', + ], + }, + }], + ['tsan==1', { + 'variables': { + 'files': [ + '../tools/sanitizers/tsan_suppressions.txt', + ], + }, + }], + ['OS=="linux" and (asan==1 or cfi_vptr==1 or msan==1 or tsan==1)', { + 'variables': { + 'files': [ + # For llvm-symbolizer. + '../third_party/llvm-build/Release+Asserts/lib/libstdc++.so.6', + ], + }, + }], + ['asan==1 or cfi_vptr==1 or msan==1 or tsan==1', { + 'variables': { + 'files': [ + '../third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer<(EXECUTABLE_SUFFIX)', + ], + }, + }], + # Workaround for https://code.google.com/p/swarming/issues/detail?id=211 + ['asan==0 or cfi_vptr==0 or msan==0 or tsan==0', { + 'variables': {}, + }], ], } \ No newline at end of file diff --git a/deps/v8/src/base/atomicops.h b/deps/v8/src/base/atomicops.h index e76b3d02d24a3f..3e628fead9172d 100644 --- a/deps/v8/src/base/atomicops.h +++ b/deps/v8/src/base/atomicops.h @@ -133,7 +133,8 @@ Atomic64 Acquire_Load(volatile const Atomic64* ptr); Atomic64 Release_Load(volatile const Atomic64* ptr); #endif // V8_HOST_ARCH_64_BIT -} } // namespace v8::base +} // namespace base +} // namespace v8 // Include our platform specific implementation. #if defined(THREAD_SANITIZER) diff --git a/deps/v8/src/base/atomicops_internals_arm64_gcc.h b/deps/v8/src/base/atomicops_internals_arm64_gcc.h index b01783e6a7e275..f24050a3e6e6a1 100644 --- a/deps/v8/src/base/atomicops_internals_arm64_gcc.h +++ b/deps/v8/src/base/atomicops_internals_arm64_gcc.h @@ -311,6 +311,7 @@ inline Atomic64 Release_Load(volatile const Atomic64* ptr) { return *ptr; } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ diff --git a/deps/v8/src/base/atomicops_internals_arm_gcc.h b/deps/v8/src/base/atomicops_internals_arm_gcc.h index e399657e13ca9a..6c8b27ea24ec69 100644 --- a/deps/v8/src/base/atomicops_internals_arm_gcc.h +++ b/deps/v8/src/base/atomicops_internals_arm_gcc.h @@ -59,7 +59,8 @@ inline void MemoryBarrier() { // variant of the target architecture is being used. This tests against // any known ARMv6 or ARMv7 variant, where it is possible to directly // use ldrex/strex instructions to implement fast atomic operations. -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ +#if defined(__ARM_ARCH_8A__) || \ + defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || \ defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ @@ -296,6 +297,7 @@ inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) { inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) { return *ptr; } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ diff --git a/deps/v8/src/base/atomicops_internals_atomicword_compat.h b/deps/v8/src/base/atomicops_internals_atomicword_compat.h index 0530ced2a44941..4f758a72990acc 100644 --- a/deps/v8/src/base/atomicops_internals_atomicword_compat.h +++ b/deps/v8/src/base/atomicops_internals_atomicword_compat.h @@ -92,7 +92,8 @@ inline AtomicWord Release_Load(volatile const AtomicWord* ptr) { reinterpret_cast(ptr)); } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // !defined(V8_HOST_ARCH_64_BIT) diff --git a/deps/v8/src/base/atomicops_internals_mac.h b/deps/v8/src/base/atomicops_internals_mac.h index 84f9dbcd75802b..c112506238adc6 100644 --- a/deps/v8/src/base/atomicops_internals_mac.h +++ b/deps/v8/src/base/atomicops_internals_mac.h @@ -210,6 +210,7 @@ inline Atomic64 Release_Load(volatile const Atomic64* ptr) { #endif // defined(__LP64__) #undef ATOMICOPS_COMPILER_BARRIER -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_MAC_H_ diff --git a/deps/v8/src/base/atomicops_internals_mips64_gcc.h b/deps/v8/src/base/atomicops_internals_mips64_gcc.h index ccb973c0391ebc..85b4e462b9db68 100644 --- a/deps/v8/src/base/atomicops_internals_mips64_gcc.h +++ b/deps/v8/src/base/atomicops_internals_mips64_gcc.h @@ -302,6 +302,7 @@ inline Atomic64 Release_Load(volatile const Atomic64* ptr) { return *ptr; } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_ diff --git a/deps/v8/src/base/atomicops_internals_mips_gcc.h b/deps/v8/src/base/atomicops_internals_mips_gcc.h index 442fdd0f96a1d3..8d65db212778e1 100644 --- a/deps/v8/src/base/atomicops_internals_mips_gcc.h +++ b/deps/v8/src/base/atomicops_internals_mips_gcc.h @@ -155,6 +155,7 @@ inline Atomic32 Release_Load(volatile const Atomic32* ptr) { return *ptr; } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_ diff --git a/deps/v8/src/base/atomicops_internals_portable.h b/deps/v8/src/base/atomicops_internals_portable.h index a3a6e74c72e53b..bb9997378624fb 100644 --- a/deps/v8/src/base/atomicops_internals_portable.h +++ b/deps/v8/src/base/atomicops_internals_portable.h @@ -132,7 +132,7 @@ inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { inline Atomic64 Release_Load(volatile const Atomic64* ptr) { return __sync_add_and_fetch(ptr, 0); } -} -} // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_PORTABLE_H_ diff --git a/deps/v8/src/base/atomicops_internals_ppc_gcc.h b/deps/v8/src/base/atomicops_internals_ppc_gcc.h index daa27b4693d665..0d16500d1ba7df 100644 --- a/deps/v8/src/base/atomicops_internals_ppc_gcc.h +++ b/deps/v8/src/base/atomicops_internals_ppc_gcc.h @@ -162,7 +162,7 @@ inline Atomic64 Release_Load(volatile const Atomic64* ptr) { } #endif -} -} // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_PPC_GCC_H_ diff --git a/deps/v8/src/base/atomicops_internals_x86_gcc.cc b/deps/v8/src/base/atomicops_internals_x86_gcc.cc index ab7dd8d091bf5b..c0310300a1504a 100644 --- a/deps/v8/src/base/atomicops_internals_x86_gcc.cc +++ b/deps/v8/src/base/atomicops_internals_x86_gcc.cc @@ -47,7 +47,8 @@ struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = { #endif }; -} } // namespace v8::base +} // namespace base +} // namespace v8 namespace { diff --git a/deps/v8/src/base/atomicops_internals_x86_gcc.h b/deps/v8/src/base/atomicops_internals_x86_gcc.h index ec87c42121246f..55bc44cd8bd4ac 100644 --- a/deps/v8/src/base/atomicops_internals_x86_gcc.h +++ b/deps/v8/src/base/atomicops_internals_x86_gcc.h @@ -267,7 +267,8 @@ inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, #endif // defined(__x86_64__) -} } // namespace v8::base +} // namespace base +} // namespace v8 #undef ATOMICOPS_COMPILER_BARRIER diff --git a/deps/v8/src/base/atomicops_internals_x86_msvc.h b/deps/v8/src/base/atomicops_internals_x86_msvc.h index adc40318e92a7c..c37bc78df6d172 100644 --- a/deps/v8/src/base/atomicops_internals_x86_msvc.h +++ b/deps/v8/src/base/atomicops_internals_x86_msvc.h @@ -197,6 +197,7 @@ inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, #endif // defined(_WIN64) -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ diff --git a/deps/v8/src/base/build_config.h b/deps/v8/src/base/build_config.h index 8016218e5cc1ee..5f66d21fcf1b0a 100644 --- a/deps/v8/src/base/build_config.h +++ b/deps/v8/src/base/build_config.h @@ -68,6 +68,10 @@ # endif #endif +#if defined(__ARM_ARCH_8A__) +# define CAN_USE_ARMV8_INSTRUCTIONS 1 +#endif + // Target architecture detection. This may be set externally. If not, detect // in the same way as the host architecture, that is, target the native diff --git a/deps/v8/src/base/cpu.cc b/deps/v8/src/base/cpu.cc index 4f587201fad68c..692494afcb4c93 100644 --- a/deps/v8/src/base/cpu.cc +++ b/deps/v8/src/base/cpu.cc @@ -691,4 +691,5 @@ CPU::CPU() #endif // V8_HOST_ARCH_PPC } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/cpu.h b/deps/v8/src/base/cpu.h index 1dc0a91f650112..ca108fa2bf9113 100644 --- a/deps/v8/src/base/cpu.h +++ b/deps/v8/src/base/cpu.h @@ -145,6 +145,7 @@ class CPU final { bool is_fp64_mode_; }; -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_CPU_H_ diff --git a/deps/v8/src/base/lazy-instance.h b/deps/v8/src/base/lazy-instance.h index a20689a16c4acc..4c0a3f897b712d 100644 --- a/deps/v8/src/base/lazy-instance.h +++ b/deps/v8/src/base/lazy-instance.h @@ -232,6 +232,7 @@ struct LazyDynamicInstance { CreateTrait, InitOnceTrait, DestroyTrait> type; }; -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_LAZY_INSTANCE_H_ diff --git a/deps/v8/src/base/logging.h b/deps/v8/src/base/logging.h index 511ebf1e9c3e5a..e4e3f49bfaffa6 100644 --- a/deps/v8/src/base/logging.h +++ b/deps/v8/src/base/logging.h @@ -11,7 +11,8 @@ #include "src/base/build_config.h" -extern "C" void V8_Fatal(const char* file, int line, const char* format, ...); +extern "C" V8_NORETURN void V8_Fatal(const char* file, int line, + const char* format, ...); // The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during @@ -28,7 +29,7 @@ extern "C" void V8_Fatal(const char* file, int line, const char* format, ...); V8_Fatal("", 0, "%s", (msg)) #define UNIMPLEMENTED() \ V8_Fatal("", 0, "unimplemented code") -#define UNREACHABLE() ((void) 0) +#define UNREACHABLE() V8_Fatal("", 0, "unreachable code") #endif @@ -153,6 +154,7 @@ void DumpBacktrace(); #define DCHECK(condition) CHECK(condition) #define DCHECK_EQ(v1, v2) CHECK_EQ(v1, v2) #define DCHECK_NE(v1, v2) CHECK_NE(v1, v2) +#define DCHECK_GT(v1, v2) CHECK_GT(v1, v2) #define DCHECK_GE(v1, v2) CHECK_GE(v1, v2) #define DCHECK_LT(v1, v2) CHECK_LT(v1, v2) #define DCHECK_LE(v1, v2) CHECK_LE(v1, v2) @@ -163,6 +165,7 @@ void DumpBacktrace(); #define DCHECK(condition) ((void) 0) #define DCHECK_EQ(v1, v2) ((void) 0) #define DCHECK_NE(v1, v2) ((void) 0) +#define DCHECK_GT(v1, v2) ((void) 0) #define DCHECK_GE(v1, v2) ((void) 0) #define DCHECK_LT(v1, v2) ((void) 0) #define DCHECK_LE(v1, v2) ((void) 0) diff --git a/deps/v8/src/base/macros.h b/deps/v8/src/base/macros.h index 6dc96f4f3ba925..f47b0b9d55c82f 100644 --- a/deps/v8/src/base/macros.h +++ b/deps/v8/src/base/macros.h @@ -417,7 +417,8 @@ template <> inline bool is_fundamental() { return true; } -} -} // namespace v8::base + +} // namespace base +} // namespace v8 #endif // V8_BASE_MACROS_H_ diff --git a/deps/v8/src/base/once.cc b/deps/v8/src/base/once.cc index eaabf40d9a53e7..818a9f2e84bca5 100644 --- a/deps/v8/src/base/once.cc +++ b/deps/v8/src/base/once.cc @@ -50,4 +50,5 @@ void CallOnceImpl(OnceType* once, PointerArgFunction init_func, void* arg) { } } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/once.h b/deps/v8/src/base/once.h index 6bf741d38a998b..790a8866e09bf6 100644 --- a/deps/v8/src/base/once.h +++ b/deps/v8/src/base/once.h @@ -97,6 +97,7 @@ inline void CallOnce(OnceType* once, } } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_ONCE_H_ diff --git a/deps/v8/src/base/platform/condition-variable.cc b/deps/v8/src/base/platform/condition-variable.cc index e5b9bd0810edb6..fcd6cf7974da4a 100644 --- a/deps/v8/src/base/platform/condition-variable.cc +++ b/deps/v8/src/base/platform/condition-variable.cc @@ -313,4 +313,5 @@ bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) { #endif // V8_OS_POSIX -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/condition-variable.h b/deps/v8/src/base/platform/condition-variable.h index 9cb706460fc0b8..72d6f28507b437 100644 --- a/deps/v8/src/base/platform/condition-variable.h +++ b/deps/v8/src/base/platform/condition-variable.h @@ -113,6 +113,7 @@ typedef LazyStaticInstance< #define LAZY_CONDITION_VARIABLE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_PLATFORM_CONDITION_VARIABLE_H_ diff --git a/deps/v8/src/base/platform/elapsed-timer.h b/deps/v8/src/base/platform/elapsed-timer.h index 3fe7e8f7205b3e..f9a9ef43619c26 100644 --- a/deps/v8/src/base/platform/elapsed-timer.h +++ b/deps/v8/src/base/platform/elapsed-timer.h @@ -92,6 +92,7 @@ class ElapsedTimer final { #endif }; -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_PLATFORM_ELAPSED_TIMER_H_ diff --git a/deps/v8/src/base/platform/mutex.cc b/deps/v8/src/base/platform/mutex.cc index 8b1e305701ffcc..14016058ae7479 100644 --- a/deps/v8/src/base/platform/mutex.cc +++ b/deps/v8/src/base/platform/mutex.cc @@ -188,4 +188,5 @@ bool RecursiveMutex::TryLock() { return true; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/mutex.h b/deps/v8/src/base/platform/mutex.h index 18e85de7bcaf6c..61df19d66a514e 100644 --- a/deps/v8/src/base/platform/mutex.h +++ b/deps/v8/src/base/platform/mutex.h @@ -210,6 +210,7 @@ class LockGuard final { DISALLOW_COPY_AND_ASSIGN(LockGuard); }; -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_PLATFORM_MUTEX_H_ diff --git a/deps/v8/src/base/platform/platform-aix.cc b/deps/v8/src/base/platform/platform-aix.cc index 03e9aa3717f9de..ea2824d8c32954 100644 --- a/deps/v8/src/base/platform/platform-aix.cc +++ b/deps/v8/src/base/platform/platform-aix.cc @@ -239,5 +239,5 @@ bool VirtualMemory::ReleaseRegion(void* base, size_t size) { bool VirtualMemory::HasLazyCommits() { return true; } -} -} // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-cygwin.cc b/deps/v8/src/base/platform/platform-cygwin.cc index 18f151ac293383..a49e28723d2182 100644 --- a/deps/v8/src/base/platform/platform-cygwin.cc +++ b/deps/v8/src/base/platform/platform-cygwin.cc @@ -252,4 +252,5 @@ bool VirtualMemory::HasLazyCommits() { return false; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-freebsd.cc b/deps/v8/src/base/platform/platform-freebsd.cc index b279e0c9268fff..8b3398039fe6cc 100644 --- a/deps/v8/src/base/platform/platform-freebsd.cc +++ b/deps/v8/src/base/platform/platform-freebsd.cc @@ -255,4 +255,5 @@ bool VirtualMemory::HasLazyCommits() { return false; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-linux.cc b/deps/v8/src/base/platform/platform-linux.cc index 2a2abfeb25cf24..a4b742adc715fb 100644 --- a/deps/v8/src/base/platform/platform-linux.cc +++ b/deps/v8/src/base/platform/platform-linux.cc @@ -388,4 +388,5 @@ bool VirtualMemory::HasLazyCommits() { return true; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-macos.cc b/deps/v8/src/base/platform/platform-macos.cc index f16f329fc35e33..419281f6694df5 100644 --- a/deps/v8/src/base/platform/platform-macos.cc +++ b/deps/v8/src/base/platform/platform-macos.cc @@ -249,4 +249,5 @@ bool VirtualMemory::HasLazyCommits() { return false; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-openbsd.cc b/deps/v8/src/base/platform/platform-openbsd.cc index 369dd8e1a6da3a..af145e2fca1176 100644 --- a/deps/v8/src/base/platform/platform-openbsd.cc +++ b/deps/v8/src/base/platform/platform-openbsd.cc @@ -286,4 +286,5 @@ bool VirtualMemory::HasLazyCommits() { return false; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-qnx.cc b/deps/v8/src/base/platform/platform-qnx.cc index b16652886e681d..3c904676273d76 100644 --- a/deps/v8/src/base/platform/platform-qnx.cc +++ b/deps/v8/src/base/platform/platform-qnx.cc @@ -312,4 +312,5 @@ bool VirtualMemory::HasLazyCommits() { return false; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-solaris.cc b/deps/v8/src/base/platform/platform-solaris.cc index 7e07f1a1e2937e..a2ce2c13f633c5 100644 --- a/deps/v8/src/base/platform/platform-solaris.cc +++ b/deps/v8/src/base/platform/platform-solaris.cc @@ -208,4 +208,5 @@ bool VirtualMemory::HasLazyCommits() { return false; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/platform-win32.cc b/deps/v8/src/base/platform/platform-win32.cc index a73dc523c41278..6afa6f9c3731a8 100644 --- a/deps/v8/src/base/platform/platform-win32.cc +++ b/deps/v8/src/base/platform/platform-win32.cc @@ -751,9 +751,19 @@ void* OS::GetRandomMmapAddr() { static void* RandomizedVirtualAlloc(size_t size, int action, int protection) { LPVOID base = NULL; + static BOOL use_aslr = -1; +#ifdef V8_HOST_ARCH_32_BIT + // Don't bother randomizing on 32-bit hosts, because they lack the room and + // don't have viable ASLR anyway. + if (use_aslr == -1 && !IsWow64Process(GetCurrentProcess(), &use_aslr)) + use_aslr = FALSE; +#else + use_aslr = TRUE; +#endif - if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { - // For exectutable pages try and randomize the allocation address + if (use_aslr && + (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS)) { + // For executable pages try and randomize the allocation address for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) { base = VirtualAlloc(OS::GetRandomMmapAddr(), size, action, protection); } @@ -823,6 +833,9 @@ void OS::Abort() { } // Make the MSVCRT do a silent abort. raise(SIGABRT); + + // Make sure function doesn't return. + abort(); } @@ -1133,9 +1146,9 @@ static std::vector LoadSymbols( WideCharToMultiByte(CP_UTF8, 0, module_entry.szExePath, -1, &lib_name[0], lib_name_length, NULL, NULL); result.push_back(OS::SharedLibraryAddress( - lib_name, reinterpret_cast(module_entry.modBaseAddr), - reinterpret_cast(module_entry.modBaseAddr + - module_entry.modBaseSize))); + lib_name, reinterpret_cast(module_entry.modBaseAddr), + reinterpret_cast(module_entry.modBaseAddr + + module_entry.modBaseSize))); cont = _Module32NextW(snapshot, &module_entry); } CloseHandle(snapshot); diff --git a/deps/v8/src/base/platform/platform.h b/deps/v8/src/base/platform/platform.h index 2d08ecbd7f6979..89d6225edebbde 100644 --- a/deps/v8/src/base/platform/platform.h +++ b/deps/v8/src/base/platform/platform.h @@ -194,7 +194,7 @@ class OS { static void Sleep(TimeDelta interval); // Abort the current process. - static void Abort(); + V8_NORETURN static void Abort(); // Debug break. static void DebugBreak(); @@ -479,6 +479,7 @@ class Thread { DISALLOW_COPY_AND_ASSIGN(Thread); }; -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_PLATFORM_PLATFORM_H_ diff --git a/deps/v8/src/base/platform/semaphore.cc b/deps/v8/src/base/platform/semaphore.cc index 0679c00d95ea4f..9e7b59a1d2cc09 100644 --- a/deps/v8/src/base/platform/semaphore.cc +++ b/deps/v8/src/base/platform/semaphore.cc @@ -75,6 +75,10 @@ bool Semaphore::WaitFor(const TimeDelta& rel_time) { Semaphore::Semaphore(int count) { DCHECK(count >= 0); +#if V8_LIBC_GLIBC + // sem_init in glibc prior to 2.1 does not zero out semaphores. + memset(&native_handle_, 0, sizeof(native_handle_)); +#endif int result = sem_init(&native_handle_, 0, count); DCHECK_EQ(0, result); USE(result); @@ -201,4 +205,5 @@ bool Semaphore::WaitFor(const TimeDelta& rel_time) { #endif // V8_OS_MACOSX -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/semaphore.h b/deps/v8/src/base/platform/semaphore.h index fa131018b37ae9..18700d1ba005f0 100644 --- a/deps/v8/src/base/platform/semaphore.h +++ b/deps/v8/src/base/platform/semaphore.h @@ -96,6 +96,7 @@ struct LazySemaphore { #define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_PLATFORM_SEMAPHORE_H_ diff --git a/deps/v8/src/base/platform/time.cc b/deps/v8/src/base/platform/time.cc index 5162182b7a3555..e847d54de821b0 100644 --- a/deps/v8/src/base/platform/time.cc +++ b/deps/v8/src/base/platform/time.cc @@ -644,4 +644,5 @@ bool TimeTicks::KernelTimestampAvailable() { #endif // V8_OS_WIN -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/platform/time.h b/deps/v8/src/base/platform/time.h index 5fc01e88fd7ac8..29300e54044577 100644 --- a/deps/v8/src/base/platform/time.h +++ b/deps/v8/src/base/platform/time.h @@ -398,6 +398,7 @@ inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) { return ticks + delta; } -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_PLATFORM_TIME_H_ diff --git a/deps/v8/src/base/utils/random-number-generator.cc b/deps/v8/src/base/utils/random-number-generator.cc index 29a48ffb05d0db..4cf06a90473096 100644 --- a/deps/v8/src/base/utils/random-number-generator.cc +++ b/deps/v8/src/base/utils/random-number-generator.cc @@ -136,4 +136,5 @@ void RandomNumberGenerator::SetSeed(int64_t seed) { seed_ = (seed ^ kMultiplier) & kMask; } -} } // namespace v8::base +} // namespace base +} // namespace v8 diff --git a/deps/v8/src/base/utils/random-number-generator.h b/deps/v8/src/base/utils/random-number-generator.h index 62c6b27b1b44aa..10f2789c7dffea 100644 --- a/deps/v8/src/base/utils/random-number-generator.h +++ b/deps/v8/src/base/utils/random-number-generator.h @@ -94,6 +94,7 @@ class RandomNumberGenerator final { int64_t seed_; }; -} } // namespace v8::base +} // namespace base +} // namespace v8 #endif // V8_BASE_UTILS_RANDOM_NUMBER_GENERATOR_H_ diff --git a/deps/v8/src/bignum-dtoa.h b/deps/v8/src/bignum-dtoa.h index d42801bd69b756..dab27badba839e 100644 --- a/deps/v8/src/bignum-dtoa.h +++ b/deps/v8/src/bignum-dtoa.h @@ -55,6 +55,7 @@ enum BignumDtoaMode { void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, Vector buffer, int* length, int* point); -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_BIGNUM_DTOA_H_ diff --git a/deps/v8/src/bignum.cc b/deps/v8/src/bignum.cc index 9baf77e7f28d64..e7c6747665f12f 100644 --- a/deps/v8/src/bignum.cc +++ b/deps/v8/src/bignum.cc @@ -68,7 +68,9 @@ static uint64_t ReadUInt64(Vector buffer, int from, int digits_to_read) { uint64_t result = 0; - for (int i = from; i < from + digits_to_read; ++i) { + int to = from + digits_to_read; + + for (int i = from; i < to; ++i) { int digit = buffer[i] - '0'; DCHECK(0 <= digit && digit <= 9); result = result * 10 + digit; diff --git a/deps/v8/src/bignum.h b/deps/v8/src/bignum.h index 7ebdae47bc1981..167c1842da4d2e 100644 --- a/deps/v8/src/bignum.h +++ b/deps/v8/src/bignum.h @@ -115,6 +115,7 @@ class Bignum { DISALLOW_COPY_AND_ASSIGN(Bignum); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_BIGNUM_H_ diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index a8a5f9768047ee..c609e578d4353f 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -6,7 +6,6 @@ #include "src/accessors.h" #include "src/api-natives.h" -#include "src/base/utils/random-number-generator.h" #include "src/code-stubs.h" #include "src/extensions/externalize-string-extension.h" #include "src/extensions/free-buffer-extension.h" @@ -164,6 +163,7 @@ class Genesis BASE_EMBEDDED { void CreateStrictModeFunctionMaps(Handle empty); void CreateStrongModeFunctionMaps(Handle empty); + void CreateIteratorMaps(); // Make the "arguments" and "caller" properties throw a TypeError on access. void AddRestrictedFunctionProperties(Handle map); @@ -174,18 +174,18 @@ class Genesis BASE_EMBEDDED { // but in the latter case we don't use the objects it produces directly, as // we have to used the deserialized ones that are linked together with the // rest of the context snapshot. - Handle CreateNewGlobals( + Handle CreateNewGlobals( v8::Local global_proxy_template, Handle global_proxy); // Hooks the given global proxy into the context. If the context was created // by deserialization then this will unhook the global proxy that was // deserialized, leaving the GC to pick it up. - void HookUpGlobalProxy(Handle global_object, + void HookUpGlobalProxy(Handle global_object, Handle global_proxy); // Similarly, we want to use the global that has been created by the templates // passed through the API. The global from the snapshot is detached from the // other objects in the snapshot. - void HookUpGlobalObject(Handle global_object, + void HookUpGlobalObject(Handle global_object, Handle outdated_contexts); // The native context has a ScriptContextTable that store declarative bindings // made in script scopes. Add a "this" binding to that table pointing to the @@ -193,12 +193,12 @@ class Genesis BASE_EMBEDDED { void InstallGlobalThisBinding(); void HookUpGlobalThisBinding(Handle outdated_contexts); // New context initialization. Used for creating a context from scratch. - void InitializeGlobal(Handle global_object, + void InitializeGlobal(Handle global_object, Handle empty_function, ContextType context_type); void InitializeExperimentalGlobal(); - // Typed arrays are not serializable and have to initialized afterwards. - void InitializeBuiltinTypedArrays(); + // Depending on the situation, expose and/or get rid of the utils object. + void ConfigureUtilsObject(ContextType context_type); #define DECLARE_FEATURE_INITIALIZATION(id, descr) \ void InitializeGlobal_##id(); @@ -370,6 +370,9 @@ static void SetObjectPrototype(Handle object, Handle proto) { void Bootstrapper::DetachGlobal(Handle env) { + env->GetIsolate()->counters()->errors_thrown_per_context()->AddSample( + env->GetErrorsThrown()); + Factory* factory = env->GetIsolate()->factory(); Handle global_proxy(JSGlobalProxy::cast(env->global_proxy())); global_proxy->set_native_context(*factory->null_value()); @@ -418,13 +421,7 @@ Handle InstallFunction(Handle target, const char* name, Builtins::Name call, bool strict_function_map = false) { Factory* const factory = target->GetIsolate()->factory(); - PropertyAttributes attributes; - if (target->IsJSBuiltinsObject()) { - attributes = - static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY); - } else { - attributes = DONT_ENUM; - } + PropertyAttributes attributes = DONT_ENUM; return InstallFunction(target, factory->InternalizeUtf8String(name), type, instance_size, maybe_prototype, call, attributes, strict_function_map); @@ -698,7 +695,8 @@ Handle Genesis::GetThrowTypeErrorIntrinsic( static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY)) .Assert(); - JSObject::PreventExtensions(function).Assert(); + if (JSObject::PreventExtensions(function, Object::THROW_ON_ERROR).IsNothing()) + DCHECK(false); return function; } @@ -793,6 +791,57 @@ void Genesis::CreateStrongModeFunctionMaps(Handle empty) { } +void Genesis::CreateIteratorMaps() { + // Create iterator-related meta-objects. + Handle iterator_prototype = + factory()->NewJSObject(isolate()->object_function(), TENURED); + Handle generator_object_prototype = + factory()->NewJSObject(isolate()->object_function(), TENURED); + Handle generator_function_prototype = + factory()->NewJSObject(isolate()->object_function(), TENURED); + SetObjectPrototype(generator_object_prototype, iterator_prototype); + + JSObject::AddProperty(generator_function_prototype, + factory()->InternalizeUtf8String("prototype"), + generator_object_prototype, + static_cast(DONT_ENUM | READ_ONLY)); + + // Create maps for generator functions and their prototypes. Store those + // maps in the native context. The "prototype" property descriptor is + // writable, non-enumerable, and non-configurable (as per ES6 draft + // 04-14-15, section 25.2.4.3). + Handle strict_function_map(strict_function_map_writable_prototype_); + // Generator functions do not have "caller" or "arguments" accessors. + Handle sloppy_generator_function_map = + Map::Copy(strict_function_map, "SloppyGeneratorFunction"); + Map::SetPrototype(sloppy_generator_function_map, + generator_function_prototype); + native_context()->set_sloppy_generator_function_map( + *sloppy_generator_function_map); + + Handle strict_generator_function_map = + Map::Copy(strict_function_map, "StrictGeneratorFunction"); + Map::SetPrototype(strict_generator_function_map, + generator_function_prototype); + native_context()->set_strict_generator_function_map( + *strict_generator_function_map); + + Handle strong_function_map(native_context()->strong_function_map()); + Handle strong_generator_function_map = + Map::Copy(strong_function_map, "StrongGeneratorFunction"); + Map::SetPrototype(strong_generator_function_map, + generator_function_prototype); + native_context()->set_strong_generator_function_map( + *strong_generator_function_map); + + Handle object_function(native_context()->object_function()); + Handle generator_object_prototype_map = Map::Create(isolate(), 0); + Map::SetPrototype(generator_object_prototype_map, generator_object_prototype); + native_context()->set_generator_object_prototype_map( + *generator_object_prototype_map); +} + + static void ReplaceAccessors(Handle map, Handle name, PropertyAttributes attributes, @@ -888,7 +937,7 @@ void Genesis::HookUpGlobalThisBinding(Handle outdated_contexts) { } -Handle Genesis::CreateNewGlobals( +Handle Genesis::CreateNewGlobals( v8::Local global_proxy_template, Handle global_proxy) { // The argument global_proxy_template aka data is an ObjectTemplateInfo. @@ -948,8 +997,8 @@ Handle Genesis::CreateNewGlobals( js_global_object_function->initial_map()->set_is_prototype_map(true); js_global_object_function->initial_map()->set_is_hidden_prototype(); js_global_object_function->initial_map()->set_dictionary_map(true); - Handle global_object = - factory()->NewGlobalObject(js_global_object_function); + Handle global_object = + factory()->NewJSGlobalObject(js_global_object_function); // Step 2: (re)initialize the global proxy object. Handle global_proxy_function; @@ -981,7 +1030,7 @@ Handle Genesis::CreateNewGlobals( } -void Genesis::HookUpGlobalProxy(Handle global_object, +void Genesis::HookUpGlobalProxy(Handle global_object, Handle global_proxy) { // Set the native context for the global object. global_object->set_native_context(*native_context()); @@ -995,11 +1044,10 @@ void Genesis::HookUpGlobalProxy(Handle global_object, } -void Genesis::HookUpGlobalObject(Handle global_object, +void Genesis::HookUpGlobalObject(Handle global_object, Handle outdated_contexts) { - Handle global_object_from_snapshot( - GlobalObject::cast(native_context()->extension())); - Handle builtins_global(native_context()->builtins()); + Handle global_object_from_snapshot( + JSGlobalObject::cast(native_context()->extension())); native_context()->set_extension(*global_object); native_context()->set_security_token(*global_object); @@ -1012,13 +1060,6 @@ void Genesis::HookUpGlobalObject(Handle global_object, context->set_global_object(*global_object); } - static const PropertyAttributes attributes = - static_cast(READ_ONLY | DONT_DELETE); - JSObject::SetOwnPropertyIgnoreAttributes(builtins_global, - factory()->global_string(), - global_object, attributes).Assert(); - // Set up the reference from the global object to the builtins object. - JSGlobalObject::cast(*global_object)->set_builtins(*builtins_global); TransferNamedProperties(global_object_from_snapshot, global_object); TransferIndexedProperties(global_object_from_snapshot, global_object); } @@ -1026,7 +1067,7 @@ void Genesis::HookUpGlobalObject(Handle global_object, // This is only called if we are not using snapshots. The equivalent // work in the snapshot case is done in HookUpGlobalObject. -void Genesis::InitializeGlobal(Handle global_object, +void Genesis::InitializeGlobal(Handle global_object, Handle empty_function, ContextType context_type) { // --- N a t i v e C o n t e x t --- @@ -1043,7 +1084,6 @@ void Genesis::InitializeGlobal(Handle global_object, Isolate* isolate = global_object->GetIsolate(); Factory* factory = isolate->factory(); - Heap* heap = isolate->heap(); Handle script_context_table = factory->NewScriptContextTable(); @@ -1061,6 +1101,7 @@ void Genesis::InitializeGlobal(Handle global_object, InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize, empty_function, Builtins::kIllegal); function_function->initial_map()->set_is_callable(); + function_function->initial_map()->set_is_constructor(true); { // --- A r r a y --- Handle array_function = @@ -1185,74 +1226,21 @@ void Genesis::InitializeGlobal(Handle global_object, DCHECK_EQ(0, initial_map->GetInObjectProperties()); - PropertyAttributes final = - static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY); - Map::EnsureDescriptorSlack(initial_map, 5); + Map::EnsureDescriptorSlack(initial_map, 1); - { - // ECMA-262, section 15.10.7.1. - DataDescriptor field(factory->source_string(), - JSRegExp::kSourceFieldIndex, final, - Representation::Tagged()); - initial_map->AppendDescriptor(&field); - } - { - // ECMA-262, section 15.10.7.2. - DataDescriptor field(factory->global_string(), - JSRegExp::kGlobalFieldIndex, final, - Representation::Tagged()); - initial_map->AppendDescriptor(&field); - } - { - // ECMA-262, section 15.10.7.3. - DataDescriptor field(factory->ignore_case_string(), - JSRegExp::kIgnoreCaseFieldIndex, final, - Representation::Tagged()); - initial_map->AppendDescriptor(&field); - } - { - // ECMA-262, section 15.10.7.4. - DataDescriptor field(factory->multiline_string(), - JSRegExp::kMultilineFieldIndex, final, - Representation::Tagged()); - initial_map->AppendDescriptor(&field); - } - { - // ECMA-262, section 15.10.7.5. - PropertyAttributes writable = - static_cast(DONT_ENUM | DONT_DELETE); - DataDescriptor field(factory->last_index_string(), - JSRegExp::kLastIndexFieldIndex, writable, - Representation::Tagged()); - initial_map->AppendDescriptor(&field); - } + // ECMA-262, section 15.10.7.5. + PropertyAttributes writable = + static_cast(DONT_ENUM | DONT_DELETE); + DataDescriptor field(factory->last_index_string(), + JSRegExp::kLastIndexFieldIndex, writable, + Representation::Tagged()); + initial_map->AppendDescriptor(&field); static const int num_fields = JSRegExp::kInObjectFieldCount; initial_map->SetInObjectProperties(num_fields); initial_map->set_unused_property_fields(0); initial_map->set_instance_size(initial_map->instance_size() + num_fields * kPointerSize); - - // RegExp prototype object is itself a RegExp. - Handle proto_map = Map::Copy(initial_map, "RegExpPrototype"); - DCHECK(proto_map->prototype() == *isolate->initial_object_prototype()); - Handle proto = factory->NewJSObjectFromMap(proto_map); - proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, - heap->query_colon_string()); - proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, - heap->false_value()); - proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, - heap->false_value()); - proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, - heap->false_value()); - proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, - Smi::FromInt(0), - SKIP_WRITE_BARRIER); // It's a Smi. - proto_map->set_is_prototype_map(true); - Map::SetPrototype(initial_map, proto); - factory->SetRegExpIrregexpData(Handle::cast(proto), - JSRegExp::IRREGEXP, factory->empty_string(), - JSRegExp::Flags(0), 0); } // Initialize the embedder data slot. @@ -1266,7 +1254,7 @@ void Genesis::InitializeGlobal(Handle global_object, Handle cons = factory->NewFunction(name); JSFunction::SetInstancePrototype(cons, Handle(native_context()->initial_object_prototype(), isolate)); - cons->SetInstanceClassName(*name); + cons->shared()->set_instance_class_name(*name); Handle json_object = factory->NewJSObject(cons, TENURED); DCHECK(json_object->IsJSObject()); JSObject::AddProperty(global, name, json_object, DONT_ENUM); @@ -1278,7 +1266,7 @@ void Genesis::InitializeGlobal(Handle global_object, JSFunction::SetInstancePrototype( cons, Handle(native_context()->initial_object_prototype(), isolate)); - cons->SetInstanceClassName(*name); + cons->shared()->set_instance_class_name(*name); Handle json_object = factory->NewJSObject(cons, TENURED); DCHECK(json_object->IsJSObject()); JSObject::AddProperty(global, name, json_object, DONT_ENUM); @@ -1542,9 +1530,8 @@ bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) { Handle extras_utils = isolate->extras_utils_object(); Handle args[] = {global, utils, extras_utils}; - return Bootstrapper::CompileNative( - isolate, name, Handle(isolate->native_context()->builtins()), - source_code, arraysize(args), args); + return Bootstrapper::CompileNative(isolate, name, source_code, + arraysize(args), args); } @@ -1556,9 +1543,8 @@ bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) { Handle global = isolate->global_object(); Handle utils = isolate->natives_utils_object(); Handle args[] = {global, utils}; - return Bootstrapper::CompileNative( - isolate, name, Handle(isolate->native_context()->builtins()), - source_code, arraysize(args), args); + return Bootstrapper::CompileNative(isolate, name, source_code, + arraysize(args), args); } @@ -1571,9 +1557,8 @@ bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) { Handle binding = isolate->extras_binding_object(); Handle extras_utils = isolate->extras_utils_object(); Handle args[] = {global, binding, extras_utils}; - return Bootstrapper::CompileNative( - isolate, name, Handle(isolate->native_context()->builtins()), - source_code, arraysize(args), args); + return Bootstrapper::CompileNative(isolate, name, source_code, + arraysize(args), args); } @@ -1587,9 +1572,8 @@ bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate, Handle binding = isolate->extras_binding_object(); Handle extras_utils = isolate->extras_utils_object(); Handle args[] = {global, binding, extras_utils}; - return Bootstrapper::CompileNative( - isolate, name, Handle(isolate->native_context()->builtins()), - source_code, arraysize(args), args); + return Bootstrapper::CompileNative(isolate, name, source_code, + arraysize(args), args); } @@ -1602,13 +1586,12 @@ bool Bootstrapper::CompileCodeStubBuiltin(Isolate* isolate, int index) { Handle exports(isolate->heap()->code_stub_exports_object()); Handle args[] = {global, exports}; bool result = - CompileNative(isolate, name, global, source_code, arraysize(args), args); + CompileNative(isolate, name, source_code, arraysize(args), args); return result; } bool Bootstrapper::CompileNative(Isolate* isolate, Vector name, - Handle receiver, Handle source, int argc, Handle argv[]) { SuppressDebug compiling_natives(isolate->debug()); @@ -1637,6 +1620,7 @@ bool Bootstrapper::CompileNative(Isolate* isolate, Vector name, Handle fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info, runtime_context); + Handle receiver = isolate->factory()->undefined_value(); // For non-extension scripts, run script to get the function wrapper. Handle wrapper; @@ -1707,7 +1691,7 @@ static Handle ResolveBuiltinIdHolder(Handle native_context, const char* holder_expr) { Isolate* isolate = native_context->GetIsolate(); Factory* factory = isolate->factory(); - Handle global(native_context->global_object()); + Handle global(native_context->global_object()); const char* period_pos = strchr(holder_expr, '.'); if (period_pos == NULL) { return Handle::cast( @@ -1736,81 +1720,75 @@ static Handle ResolveBuiltinIdHolder(Handle native_context, template -Data* SetBuiltinTypedArray(Isolate* isolate, Handle builtins, - ExternalArrayType type, Data* data, - size_t num_elements, const char* name, - const SharedFlag shared = SharedFlag::kNotShared, - const PretenureFlag pretenure = TENURED) { - size_t byte_length = num_elements * sizeof(*data); +Handle CreateTypedArray(Isolate* isolate, ExternalArrayType type, + size_t num_elements, Data** data) { + size_t byte_length = num_elements * sizeof(**data); Handle buffer = - isolate->factory()->NewJSArrayBuffer(shared, pretenure); - bool is_external = data != nullptr; + isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared, TENURED); + bool is_external = (*data != nullptr); if (!is_external) { - data = reinterpret_cast( + *data = reinterpret_cast( isolate->array_buffer_allocator()->Allocate(byte_length)); } - JSArrayBuffer::Setup(buffer, isolate, is_external, data, byte_length, shared); - - Handle typed_array = isolate->factory()->NewJSTypedArray( - type, buffer, 0, num_elements, pretenure); - Handle name_string = isolate->factory()->InternalizeUtf8String(name); - // Reset property cell type before (re)initializing. - JSBuiltinsObject::InvalidatePropertyCell(builtins, name_string); - JSObject::SetOwnPropertyIgnoreAttributes(builtins, name_string, typed_array, - FROZEN) - .Assert(); - return data; -} - - -void Genesis::InitializeBuiltinTypedArrays() { - Handle builtins(native_context()->builtins()); - { // Initially seed the per-context random number generator using the - // per-isolate random number generator. - const size_t num_elements = 2; - const size_t num_bytes = num_elements * sizeof(uint32_t); - uint32_t* state = SetBuiltinTypedArray(isolate(), builtins, - kExternalUint32Array, NULL, - num_elements, "rngstate"); - do { - isolate()->random_number_generator()->NextBytes(state, num_bytes); - } while (state[0] == 0 || state[1] == 0); + JSArrayBuffer::Setup(buffer, isolate, is_external, *data, byte_length, + SharedFlag::kNotShared); + return isolate->factory()->NewJSTypedArray(type, buffer, 0, num_elements, + TENURED); +} + + +void Genesis::ConfigureUtilsObject(ContextType context_type) { + switch (context_type) { + // We still need the utils object to find debug functions. + case DEBUG_CONTEXT: + return; + // Expose the natives in global if a valid name for it is specified. + case FULL_CONTEXT: { + // We still need the utils object after deserialization. + if (isolate()->serializer_enabled()) return; + if (FLAG_expose_natives_as == NULL) break; + if (strlen(FLAG_expose_natives_as) == 0) break; + HandleScope scope(isolate()); + Handle natives_key = + factory()->InternalizeUtf8String(FLAG_expose_natives_as); + uint32_t dummy_index; + if (natives_key->AsArrayIndex(&dummy_index)) break; + Handle utils = isolate()->natives_utils_object(); + Handle global = isolate()->global_object(); + JSObject::AddProperty(global, natives_key, utils, DONT_ENUM); + break; + } + case THIN_CONTEXT: + break; } - { // Initialize trigonometric lookup tables and constants. - const size_t num_elements = arraysize(fdlibm::MathConstants::constants); - double* data = const_cast(fdlibm::MathConstants::constants); - SetBuiltinTypedArray(isolate(), builtins, kExternalFloat64Array, - data, num_elements, "kMath"); - } + // The utils object can be removed for cases that reach this point. + native_context()->set_natives_utils_object(heap()->undefined_value()); - { // Initialize a result array for rempio2 calculation - const size_t num_elements = 2; - double* data = - SetBuiltinTypedArray(isolate(), builtins, kExternalFloat64Array, - NULL, num_elements, "rempio2result"); - for (size_t i = 0; i < num_elements; i++) data[i] = 0; - } +#ifdef DEBUG + JSGlobalObject* dummy = native_context()->runtime_context()->global_object(); + DCHECK_EQ(0, dummy->elements()->length()); + DCHECK_EQ(0, GlobalDictionary::cast(dummy->properties())->NumberOfElements()); +#endif } void Bootstrapper::ExportFromRuntime(Isolate* isolate, Handle container) { + Factory* factory = isolate->factory(); HandleScope scope(isolate); -#define EXPORT_PRIVATE_SYMBOL(NAME) \ - Handle NAME##_name = \ - isolate->factory()->NewStringFromAsciiChecked(#NAME); \ - JSObject::AddProperty(container, NAME##_name, isolate->factory()->NAME(), \ - NONE); + Handle native_context = isolate->native_context(); +#define EXPORT_PRIVATE_SYMBOL(NAME) \ + Handle NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \ + JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE); PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL) #undef EXPORT_PRIVATE_SYMBOL -#define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION) \ - Handle NAME##_name = \ - isolate->factory()->NewStringFromAsciiChecked(#NAME); \ - JSObject::AddProperty(container, NAME##_name, isolate->factory()->NAME(), \ - NONE); +#define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION) \ + Handle NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \ + JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE); PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL) + WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL) #undef EXPORT_PUBLIC_SYMBOL { @@ -1822,7 +1800,7 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate, Handle feedback_vector = TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate); apply->shared()->set_feedback_vector(*feedback_vector); - isolate->native_context()->set_reflect_apply(*apply); + native_context->set_reflect_apply(*apply); } { @@ -1834,7 +1812,204 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate, Handle feedback_vector = TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate); construct->shared()->set_feedback_vector(*feedback_vector); - isolate->native_context()->set_reflect_construct(*construct); + native_context->set_reflect_construct(*construct); + } + + Handle iterator_prototype; + + { + PrototypeIterator iter(native_context->generator_object_prototype_map()); + iter.Advance(); // Advance to the prototype of generator_object_prototype. + iterator_prototype = Handle(iter.GetCurrent()); + + JSObject::AddProperty(container, + factory->InternalizeUtf8String("IteratorPrototype"), + iterator_prototype, NONE); + } + + { + PrototypeIterator iter(native_context->sloppy_generator_function_map()); + Handle generator_function_prototype(iter.GetCurrent()); + + JSObject::AddProperty( + container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"), + generator_function_prototype, NONE); + + static const bool kUseStrictFunctionMap = true; + Handle generator_function_function = + InstallFunction(container, "GeneratorFunction", JS_FUNCTION_TYPE, + JSFunction::kSize, generator_function_prototype, + Builtins::kIllegal, kUseStrictFunctionMap); + generator_function_function->initial_map()->set_is_callable(); + generator_function_function->initial_map()->set_is_constructor(true); + } + + { // -- S e t I t e r a t o r + Handle set_iterator_prototype = + isolate->factory()->NewJSObject(isolate->object_function(), TENURED); + SetObjectPrototype(set_iterator_prototype, iterator_prototype); + Handle set_iterator_function = InstallFunction( + container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize, + set_iterator_prototype, Builtins::kIllegal); + native_context->set_set_iterator_map(set_iterator_function->initial_map()); + } + + { // -- M a p I t e r a t o r + Handle map_iterator_prototype = + isolate->factory()->NewJSObject(isolate->object_function(), TENURED); + SetObjectPrototype(map_iterator_prototype, iterator_prototype); + Handle map_iterator_function = InstallFunction( + container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize, + map_iterator_prototype, Builtins::kIllegal); + native_context->set_map_iterator_map(map_iterator_function->initial_map()); + } + + { // -- S c r i p t + // Builtin functions for Script. + Handle script_fun = InstallFunction( + container, "Script", JS_VALUE_TYPE, JSValue::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + Handle prototype = + factory->NewJSObject(isolate->object_function(), TENURED); + Accessors::FunctionSetPrototype(script_fun, prototype).Assert(); + native_context->set_script_function(*script_fun); + + Handle script_map = Handle(script_fun->initial_map()); + Map::EnsureDescriptorSlack(script_map, 15); + + PropertyAttributes attribs = + static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY); + + Handle script_column = + Accessors::ScriptColumnOffsetInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_column->name())), script_column, + attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_id = Accessors::ScriptIdInfo(isolate, attribs); + { + AccessorConstantDescriptor d(Handle(Name::cast(script_id->name())), + script_id, attribs); + script_map->AppendDescriptor(&d); + } + + + Handle script_name = + Accessors::ScriptNameInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_name->name())), script_name, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_line = + Accessors::ScriptLineOffsetInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_line->name())), script_line, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_source = + Accessors::ScriptSourceInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_source->name())), script_source, + attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_type = + Accessors::ScriptTypeInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_type->name())), script_type, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_compilation_type = + Accessors::ScriptCompilationTypeInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_compilation_type->name())), + script_compilation_type, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_line_ends = + Accessors::ScriptLineEndsInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_line_ends->name())), script_line_ends, + attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_context_data = + Accessors::ScriptContextDataInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_context_data->name())), + script_context_data, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_eval_from_script = + Accessors::ScriptEvalFromScriptInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_eval_from_script->name())), + script_eval_from_script, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_eval_from_script_position = + Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_eval_from_script_position->name())), + script_eval_from_script_position, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_eval_from_function_name = + Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_eval_from_function_name->name())), + script_eval_from_function_name, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_source_url = + Accessors::ScriptSourceUrlInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_source_url->name())), + script_source_url, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_source_mapping_url = + Accessors::ScriptSourceMappingUrlInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_source_mapping_url->name())), + script_source_mapping_url, attribs); + script_map->AppendDescriptor(&d); + } + + Handle script_is_embedder_debug_script = + Accessors::ScriptIsEmbedderDebugScriptInfo(isolate, attribs); + { + AccessorConstantDescriptor d( + Handle(Name::cast(script_is_embedder_debug_script->name())), + script_is_embedder_debug_script, attribs); + script_map->AppendDescriptor(&d); + } } } @@ -1851,9 +2026,8 @@ void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate, isolate->factory()->ToBoolean(FLAG), NONE); \ } - INITIALIZE_FLAG(FLAG_harmony_regexps) - INITIALIZE_FLAG(FLAG_harmony_unicode_regexps) INITIALIZE_FLAG(FLAG_harmony_tostring) + INITIALIZE_FLAG(FLAG_harmony_tolength) #undef INITIALIZE_FLAG } @@ -1864,30 +2038,73 @@ void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate, EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_modules) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_array_includes) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrow_functions) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_proxies) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_function) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_let) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_rest_parameters) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_default_parameters) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spread_calls) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_observe) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spread_arrays) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_new_target) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_concat_spreadable) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexps) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode_regexps) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tostring) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_completion) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tolength) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions) + + +static void SimpleInstallFunction(Handle& base, const char* name, + Builtins::Name call, int len, bool adapt) { + Handle fun = + InstallFunction(base, name, JS_OBJECT_TYPE, JSObject::kHeaderSize, + MaybeHandle(), call); + if (adapt) { + fun->shared()->set_internal_formal_parameter_count(len); + } else { + fun->shared()->DontAdaptArguments(); + } + fun->shared()->set_length(len); +} + + +void InstallPublicSymbol(Factory* factory, Handle native_context, + const char* name, Handle value) { + Handle global( + JSGlobalObject::cast(native_context->global_object())); + Handle symbol_string = factory->InternalizeUtf8String("Symbol"); + Handle symbol = Handle::cast( + JSObject::GetProperty(global, symbol_string).ToHandleChecked()); + Handle name_string = factory->InternalizeUtf8String(name); + PropertyAttributes attributes = + static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY); + JSObject::AddProperty(symbol, name_string, value, attributes); +} + + +void Genesis::InitializeGlobal_harmony_tostring() { + if (!FLAG_harmony_tostring) return; + InstallPublicSymbol(factory(), native_context(), "toStringTag", + factory()->to_string_tag_symbol()); +} + + +void Genesis::InitializeGlobal_harmony_concat_spreadable() { + if (!FLAG_harmony_concat_spreadable) return; + InstallPublicSymbol(factory(), native_context(), "isConcatSpreadable", + factory()->is_concat_spreadable_symbol()); +} -void Genesis::InitializeGlobal_harmony_tolength() { - Handle builtins(native_context()->builtins()); - Handle flag(factory()->ToBoolean(FLAG_harmony_tolength)); - Runtime::SetObjectProperty(isolate(), builtins, - factory()->harmony_tolength_string(), flag, - STRICT).Assert(); +void Genesis::InitializeGlobal_harmony_regexp_subclass() { + if (!FLAG_harmony_regexp_subclass) return; + InstallPublicSymbol(factory(), native_context(), "match", + factory()->match_symbol()); + InstallPublicSymbol(factory(), native_context(), "replace", + factory()->replace_symbol()); + InstallPublicSymbol(factory(), native_context(), "search", + factory()->search_symbol()); + InstallPublicSymbol(factory(), native_context(), "split", + factory()->split_symbol()); } @@ -1898,11 +2115,31 @@ void Genesis::InitializeGlobal_harmony_reflect() { native_context()->global_object())); Handle reflect_string = factory()->NewStringFromStaticChars("Reflect"); - Handle reflect = + Handle reflect = factory()->NewJSObject(isolate()->object_function(), TENURED); JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM); -} + SimpleInstallFunction(reflect, "defineProperty", + Builtins::kReflectDefineProperty, 3, true); + SimpleInstallFunction(reflect, "deleteProperty", + Builtins::kReflectDeleteProperty, 2, true); + SimpleInstallFunction(reflect, "get", + Builtins::kReflectGet, 3, false); + SimpleInstallFunction(reflect, "getOwnPropertyDescriptor", + Builtins::kReflectGetOwnPropertyDescriptor, 2, true); + SimpleInstallFunction(reflect, "getPrototypeOf", + Builtins::kReflectGetPrototypeOf, 1, true); + SimpleInstallFunction(reflect, "has", + Builtins::kReflectHas, 2, true); + SimpleInstallFunction(reflect, "isExtensible", + Builtins::kReflectIsExtensible, 1, true); + SimpleInstallFunction(reflect, "preventExtensions", + Builtins::kReflectPreventExtensions, 1, true); + SimpleInstallFunction(reflect, "set", + Builtins::kReflectSet, 3, false); + SimpleInstallFunction(reflect, "setPrototypeOf", + Builtins::kReflectSetPrototypeOf, 2, true); +} void Genesis::InitializeGlobal_harmony_sharedarraybuffer() { @@ -1932,19 +2169,19 @@ void Genesis::InitializeGlobal_harmony_simd() { JSFunction::SetInstancePrototype( cons, Handle(native_context()->initial_object_prototype(), isolate)); - cons->SetInstanceClassName(*name); + cons->shared()->set_instance_class_name(*name); Handle simd_object = factory->NewJSObject(cons, TENURED); DCHECK(simd_object->IsJSObject()); JSObject::AddProperty(global, name, simd_object, DONT_ENUM); // Install SIMD type functions. Set the instance class names since -// InstallFunction only does this when we install on the GlobalObject. +// InstallFunction only does this when we install on the JSGlobalObject. #define SIMD128_INSTALL_FUNCTION(TYPE, Type, type, lane_count, lane_type) \ Handle type##_function = InstallFunction( \ simd_object, #Type, JS_VALUE_TYPE, JSValue::kSize, \ isolate->initial_object_prototype(), Builtins::kIllegal); \ native_context()->set_##type##_function(*type##_function); \ - type##_function->SetInstanceClassName(*factory->Type##_string()); + type##_function->shared()->set_instance_class_name(*factory->Type##_string()); SIMD128_TYPES(SIMD128_INSTALL_FUNCTION) #undef SIMD128_INSTALL_FUNCTION } @@ -1996,50 +2233,30 @@ Handle Genesis::InstallInternalArray(Handle target, bool Genesis::InstallNatives(ContextType context_type) { HandleScope scope(isolate()); - // Create a function for the builtins object. Allocate space for the - // JavaScript builtins, a reference to the builtins object - // (itself) and a reference to the native_context directly in the object. - Handle code = Handle( - isolate()->builtins()->builtin(Builtins::kIllegal)); - Handle builtins_fun = factory()->NewFunction( - factory()->empty_string(), code, JS_BUILTINS_OBJECT_TYPE, - JSBuiltinsObject::kSize); - - Handle name = - factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("builtins")); - builtins_fun->shared()->set_instance_class_name(*name); - builtins_fun->initial_map()->set_dictionary_map(true); - builtins_fun->initial_map()->set_prototype(heap()->null_value()); - - // Allocate the builtins object. - Handle builtins = - Handle::cast(factory()->NewGlobalObject(builtins_fun)); - builtins->set_builtins(*builtins); - builtins->set_native_context(*native_context()); - builtins->set_global_proxy(native_context()->global_proxy()); - - - // Set up the 'builtin' property, which refers to the js builtins object. - static const PropertyAttributes attributes = - static_cast(READ_ONLY | DONT_DELETE); - Handle builtins_string = - factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("builtins")); - JSObject::AddProperty(builtins, builtins_string, builtins, attributes); - - // Set up the reference from the global object to the builtins object. - JSGlobalObject::cast(native_context()->global_object())-> - set_builtins(*builtins); - // Create a bridge function that has context in the native context. Handle bridge = factory()->NewFunction(factory()->empty_string()); DCHECK(bridge->context() == *isolate()->native_context()); - // Allocate the builtins context. - Handle context = - factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); - context->set_global_object(*builtins); // override builtins global object - - native_context()->set_runtime_context(*context); + // Allocate the runtime context. + { + Handle context = + factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); + native_context()->set_runtime_context(*context); + Handle code = isolate()->builtins()->Illegal(); + Handle global_fun = + factory()->NewFunction(factory()->empty_string(), code, + JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize); + global_fun->initial_map()->set_dictionary_map(true); + global_fun->initial_map()->set_prototype(heap()->null_value()); + Handle dummy_global = + Handle::cast(factory()->NewJSGlobalObject(global_fun)); + dummy_global->set_native_context(*native_context()); + dummy_global->set_global_proxy(native_context()->global_proxy()); + context->set_global_object(*dummy_global); + // Something went wrong if we actually need to write into the dummy global. + dummy_global->set_properties(*GlobalDictionary::New(isolate(), 0)); + dummy_global->set_elements(heap()->empty_fixed_array()); + } // Set up the utils object as shared container between native scripts. Handle utils = factory()->NewJSObject(isolate()->object_function()); @@ -2065,166 +2282,13 @@ bool Genesis::InstallNatives(ContextType context_type) { // A thin context is ready at this point. if (context_type == THIN_CONTEXT) return true; - if (FLAG_expose_natives_as != NULL) { - Handle utils_key = factory()->NewStringFromAsciiChecked("utils"); - JSObject::AddProperty(builtins, utils_key, utils, NONE); - } - - { // -- S c r i p t - // Builtin functions for Script. - Handle script_fun = InstallFunction( - builtins, "Script", JS_VALUE_TYPE, JSValue::kSize, - isolate()->initial_object_prototype(), Builtins::kIllegal); - Handle prototype = - factory()->NewJSObject(isolate()->object_function(), TENURED); - Accessors::FunctionSetPrototype(script_fun, prototype).Assert(); - native_context()->set_script_function(*script_fun); - - Handle script_map = Handle(script_fun->initial_map()); - Map::EnsureDescriptorSlack(script_map, 15); - - PropertyAttributes attribs = - static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY); - - Handle script_column = - Accessors::ScriptColumnOffsetInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_column->name())), script_column, - attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_id = - Accessors::ScriptIdInfo(isolate(), attribs); - { - AccessorConstantDescriptor d(Handle(Name::cast(script_id->name())), - script_id, attribs); - script_map->AppendDescriptor(&d); - } - - - Handle script_name = - Accessors::ScriptNameInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_name->name())), script_name, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_line = - Accessors::ScriptLineOffsetInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_line->name())), script_line, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_source = - Accessors::ScriptSourceInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_source->name())), script_source, - attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_type = - Accessors::ScriptTypeInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_type->name())), script_type, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_compilation_type = - Accessors::ScriptCompilationTypeInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_compilation_type->name())), - script_compilation_type, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_line_ends = - Accessors::ScriptLineEndsInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_line_ends->name())), script_line_ends, - attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_context_data = - Accessors::ScriptContextDataInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_context_data->name())), - script_context_data, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_eval_from_script = - Accessors::ScriptEvalFromScriptInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_eval_from_script->name())), - script_eval_from_script, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_eval_from_script_position = - Accessors::ScriptEvalFromScriptPositionInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_eval_from_script_position->name())), - script_eval_from_script_position, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_eval_from_function_name = - Accessors::ScriptEvalFromFunctionNameInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_eval_from_function_name->name())), - script_eval_from_function_name, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_source_url = - Accessors::ScriptSourceUrlInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_source_url->name())), - script_source_url, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_source_mapping_url = - Accessors::ScriptSourceMappingUrlInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_source_mapping_url->name())), - script_source_mapping_url, attribs); - script_map->AppendDescriptor(&d); - } - - Handle script_is_embedder_debug_script = - Accessors::ScriptIsEmbedderDebugScriptInfo(isolate(), attribs); - { - AccessorConstantDescriptor d( - Handle(Name::cast(script_is_embedder_debug_script->name())), - script_is_embedder_debug_script, attribs); - script_map->AppendDescriptor(&d); - } - } { // Builtin function for OpaqueReference -- a JSValue-based object, // that keeps its field isolated from JavaScript code. It may store // objects, that JavaScript code may not access. - Handle opaque_reference_fun = InstallFunction( - builtins, "OpaqueReference", JS_VALUE_TYPE, JSValue::kSize, - isolate()->initial_object_prototype(), Builtins::kIllegal); + Handle opaque_reference_fun = factory()->NewFunction( + factory()->empty_string(), isolate()->builtins()->Illegal(), + isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize); Handle prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert(); @@ -2246,96 +2310,6 @@ bool Genesis::InstallNatives(ContextType context_type) { InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS); } - { // -- S e t I t e r a t o r - Handle set_iterator_function = InstallFunction( - builtins, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize, - isolate()->initial_object_prototype(), Builtins::kIllegal); - native_context()->set_set_iterator_map( - set_iterator_function->initial_map()); - } - - { // -- M a p I t e r a t o r - Handle map_iterator_function = InstallFunction( - builtins, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize, - isolate()->initial_object_prototype(), Builtins::kIllegal); - native_context()->set_map_iterator_map( - map_iterator_function->initial_map()); - } - - { - // Create generator meta-objects and install them on the builtins object. - Handle builtins(native_context()->builtins()); - Handle iterator_prototype = - factory()->NewJSObject(isolate()->object_function(), TENURED); - Handle generator_object_prototype = - factory()->NewJSObject(isolate()->object_function(), TENURED); - Handle generator_function_prototype = - factory()->NewJSObject(isolate()->object_function(), TENURED); - SetObjectPrototype(generator_object_prototype, iterator_prototype); - JSObject::AddProperty( - builtins, factory()->InternalizeUtf8String("$iteratorPrototype"), - iterator_prototype, - static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY)); - JSObject::AddProperty( - builtins, - factory()->InternalizeUtf8String("GeneratorFunctionPrototype"), - generator_function_prototype, - static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY)); - - JSObject::AddProperty( - generator_function_prototype, - factory()->InternalizeUtf8String("prototype"), - generator_object_prototype, - static_cast(DONT_ENUM | READ_ONLY)); - - static const bool kUseStrictFunctionMap = true; - Handle generator_function_function = - InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, - JSFunction::kSize, generator_function_prototype, - Builtins::kIllegal, kUseStrictFunctionMap); - generator_function_function->initial_map()->set_is_callable(); - - // Create maps for generator functions and their prototypes. Store those - // maps in the native context. The "prototype" property descriptor is - // writable, non-enumerable, and non-configurable (as per ES6 draft - // 04-14-15, section 25.2.4.3). - Handle strict_function_map(strict_function_map_writable_prototype_); - // Generator functions do not have "caller" or "arguments" accessors. - Handle sloppy_generator_function_map = - Map::Copy(strict_function_map, "SloppyGeneratorFunction"); - Map::SetPrototype(sloppy_generator_function_map, - generator_function_prototype); - native_context()->set_sloppy_generator_function_map( - *sloppy_generator_function_map); - - Handle strict_generator_function_map = - Map::Copy(strict_function_map, "StrictGeneratorFunction"); - Map::SetPrototype(strict_generator_function_map, - generator_function_prototype); - native_context()->set_strict_generator_function_map( - *strict_generator_function_map); - - Handle strong_function_map(native_context()->strong_function_map()); - Handle strong_generator_function_map = - Map::Copy(strong_function_map, "StrongGeneratorFunction"); - Map::SetPrototype(strong_generator_function_map, - generator_function_prototype); - native_context()->set_strong_generator_function_map( - *strong_generator_function_map); - - Handle object_function(native_context()->object_function()); - Handle generator_object_prototype_map = Map::Create(isolate(), 0); - Map::SetPrototype(generator_object_prototype_map, - generator_object_prototype); - native_context()->set_generator_object_prototype_map( - *generator_object_prototype_map); - } - - if (FLAG_disable_native_files) { - PrintF("Warning: Running without installed natives!\n"); - return true; - } - // Run the rest of the native scripts. while (builtin_index < Natives::GetBuiltinsCount()) { if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false; @@ -2547,12 +2521,6 @@ bool Genesis::InstallNatives(ContextType context_type) { } } -#ifdef VERIFY_HEAP - if (FLAG_verify_heap) { - builtins->ObjectVerify(); - } -#endif - return true; } @@ -2564,9 +2532,7 @@ bool Genesis::InstallExperimentalNatives() { static const char* harmony_modules_natives[] = {nullptr}; static const char* harmony_regexps_natives[] = {"native harmony-regexp.js", nullptr}; - static const char* harmony_arrow_functions_natives[] = {nullptr}; - static const char* harmony_tostring_natives[] = {"native harmony-tostring.js", - nullptr}; + static const char* harmony_tostring_natives[] = {nullptr}; static const char* harmony_sloppy_natives[] = {nullptr}; static const char* harmony_sloppy_function_natives[] = {nullptr}; static const char* harmony_sloppy_let_natives[] = {nullptr}; @@ -2575,20 +2541,18 @@ bool Genesis::InstallExperimentalNatives() { static const char* harmony_default_parameters_natives[] = {nullptr}; static const char* harmony_reflect_natives[] = {"native harmony-reflect.js", nullptr}; - static const char* harmony_spread_calls_natives[] = { - "native harmony-spread.js", nullptr}; static const char* harmony_destructuring_natives[] = {nullptr}; static const char* harmony_object_observe_natives[] = { "native harmony-object-observe.js", nullptr}; - static const char* harmony_spread_arrays_natives[] = {nullptr}; static const char* harmony_sharedarraybuffer_natives[] = { "native harmony-sharedarraybuffer.js", "native harmony-atomics.js", NULL}; - static const char* harmony_new_target_natives[] = {nullptr}; - static const char* harmony_concat_spreadable_natives[] = { - "native harmony-concat-spreadable.js", nullptr}; + static const char* harmony_concat_spreadable_natives[] = {nullptr}; static const char* harmony_simd_natives[] = {"native harmony-simd.js", nullptr}; static const char* harmony_tolength_natives[] = {nullptr}; + static const char* harmony_completion_natives[] = {nullptr}; + static const char* harmony_do_expressions_natives[] = {nullptr}; + static const char* harmony_regexp_subclass_natives[] = {nullptr}; for (int i = ExperimentalNatives::GetDebuggerCount(); i < ExperimentalNatives::GetBuiltinsCount(); i++) { @@ -2753,16 +2717,6 @@ bool Genesis::InstallSpecialObjects(Handle native_context) { Handle stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate); JSObject::AddProperty(Error, name, stack_trace_limit, NONE); - // Expose the natives in global if a name for it is specified. - if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { - Handle natives_key = - factory->InternalizeUtf8String(FLAG_expose_natives_as); - uint32_t dummy_index; - if (natives_key->AsArrayIndex(&dummy_index)) return true; - Handle natives(global->builtins()); - JSObject::AddProperty(global, natives_key, natives, DONT_ENUM); - } - // Expose the debug global object in global if a name for it is specified. if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { // If loading fails we just bail out without installing the @@ -3023,7 +2977,7 @@ void Genesis::TransferNamedProperties(Handle from, } } } - } else if (from->IsGlobalObject()) { + } else if (from->IsJSGlobalObject()) { Handle properties = Handle(from->global_dictionary()); int capacity = properties->Capacity(); @@ -3190,13 +3144,11 @@ Genesis::Genesis(Isolate* isolate, Map::TraceAllTransitions(object_fun->initial_map()); } #endif - Handle global_object = + Handle global_object = CreateNewGlobals(global_proxy_template, global_proxy); HookUpGlobalProxy(global_object, global_proxy); HookUpGlobalObject(global_object, outdated_contexts); - native_context()->builtins()->set_global_proxy( - native_context()->global_proxy()); HookUpGlobalThisBinding(outdated_contexts); if (!ConfigureGlobalObjects(global_proxy_template)) return; @@ -3206,7 +3158,8 @@ Genesis::Genesis(Isolate* isolate, Handle empty_function = CreateEmptyFunction(isolate); CreateStrictModeFunctionMaps(empty_function); CreateStrongModeFunctionMaps(empty_function); - Handle global_object = + CreateIteratorMaps(); + Handle global_object = CreateNewGlobals(global_proxy_template, global_proxy); HookUpGlobalProxy(global_object, global_proxy); InitializeGlobal(global_object, empty_function, context_type); @@ -3221,6 +3174,9 @@ Genesis::Genesis(Isolate* isolate, if (!ConfigureGlobalObjects(global_proxy_template)) return; } isolate->counters()->contexts_created_from_scratch()->Increment(); + // Re-initialize the counter because it got incremented during snapshot + // creation. + isolate->native_context()->set_errors_thrown(Smi::FromInt(0)); } // Install experimental natives. Do not include them into the @@ -3234,20 +3190,17 @@ Genesis::Genesis(Isolate* isolate, if (FLAG_experimental_extras) { if (!InstallExperimentalExtraNatives()) return; } - - // By now the utils object is useless and can be removed. - native_context()->set_natives_utils_object( - isolate->heap()->undefined_value()); } // The serializer cannot serialize typed arrays. Reset those typed arrays // for each new context. - InitializeBuiltinTypedArrays(); } else if (context_type == DEBUG_CONTEXT) { DCHECK(!isolate->serializer_enabled()); InitializeExperimentalGlobal(); if (!InstallDebuggerNatives()) return; } + ConfigureUtilsObject(context_type); + // Check that the script context table is empty except for the 'this' binding. // We do not need script contexts for native scripts. if (!FLAG_global_var_shortcuts) { diff --git a/deps/v8/src/bootstrapper.h b/deps/v8/src/bootstrapper.h index 659d74aad257f1..2baa8ff61a5c76 100644 --- a/deps/v8/src/bootstrapper.h +++ b/deps/v8/src/bootstrapper.h @@ -110,8 +110,8 @@ class Bootstrapper final { SourceCodeCache* extensions_cache() { return &extensions_cache_; } static bool CompileNative(Isolate* isolate, Vector name, - Handle receiver, Handle source, - int argc, Handle argv[]); + Handle source, int argc, + Handle argv[]); static bool CompileBuiltin(Isolate* isolate, int index); static bool CompileExperimentalBuiltin(Isolate* isolate, int index); static bool CompileExtraBuiltin(Isolate* isolate, int index); @@ -176,6 +176,7 @@ class NativesExternalStringResource final size_t length_; }; -}} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_BOOTSTRAPPER_H_ diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc index 13225d2065b4f8..e4ceec99be4f17 100644 --- a/deps/v8/src/builtins.cc +++ b/deps/v8/src/builtins.cc @@ -17,6 +17,7 @@ #include "src/isolate-inl.h" #include "src/messages.h" #include "src/profiler/cpu-profiler.h" +#include "src/property-descriptor.h" #include "src/prototype.h" #include "src/vm-state-inl.h" @@ -196,16 +197,12 @@ inline bool ClampedToInteger(Object* object, int* out) { inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle object, int* out) { - Map* arguments_map = - isolate->context()->native_context()->sloppy_arguments_map(); - if (object->map() != arguments_map || !object->HasFastElements()) { - return false; - } + Map* arguments_map = isolate->native_context()->sloppy_arguments_map(); + if (object->map() != arguments_map) return false; + DCHECK(object->HasFastElements()); Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); - if (!len_obj->IsSmi()) { - return false; - } - *out = Smi::cast(len_obj)->value(); + if (!len_obj->IsSmi()) return false; + *out = Max(0, Smi::cast(len_obj)->value()); return *out <= object->elements()->length(); } @@ -992,11 +989,11 @@ bool IterateElements(Isolate* isolate, Handle receiver, uint32_t length = 0; if (receiver->IsJSArray()) { - Handle array(Handle::cast(receiver)); + Handle array = Handle::cast(receiver); length = static_cast(array->length()->Number()); } else { Handle val; - Handle key(isolate->heap()->length_string(), isolate); + Handle key = isolate->factory()->length_string(); ASSIGN_RETURN_ON_EXCEPTION_VALUE( isolate, val, Runtime::GetObjectProperty(isolate, receiver, key), false); @@ -1082,6 +1079,14 @@ bool IterateElements(Isolate* isolate, Handle receiver, break; } case DICTIONARY_ELEMENTS: { + // CollectElementIndices() can't be called when there's a JSProxy + // on the prototype chain. + for (PrototypeIterator iter(isolate, receiver); !iter.IsAtEnd(); + iter.Advance()) { + if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { + return IterateElementsSlow(isolate, receiver, length, visitor); + } + } Handle dict(receiver->element_dictionary()); List indices(dict->Capacity() / 2); // Collect all indices in the object and the prototypes less @@ -1444,6 +1449,268 @@ BUILTIN(ArrayConcat) { } +// ES6 section 26.1.3 Reflect.defineProperty +BUILTIN(ReflectDefineProperty) { + HandleScope scope(isolate); + DCHECK_EQ(4, args.length()); + Handle target = args.at(1); + Handle key = args.at(2); + Handle attributes = args.at(3); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.defineProperty"))); + } + + Handle name; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, + Object::ToName(isolate, key)); + + PropertyDescriptor desc; + if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) { + return isolate->heap()->exception(); + } + + bool result = + JSReceiver::DefineOwnProperty(isolate, Handle::cast(target), + name, &desc, Object::DONT_THROW); + if (isolate->has_pending_exception()) return isolate->heap()->exception(); + // TODO(neis): Make DefineOwnProperty return Maybe. + return *isolate->factory()->ToBoolean(result); +} + + +// ES6 section 26.1.4 Reflect.deleteProperty +BUILTIN(ReflectDeleteProperty) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + Handle target = args.at(1); + Handle key = args.at(2); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.deleteProperty"))); + } + + Handle name; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, + Object::ToName(isolate, key)); + + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, JSReceiver::DeletePropertyOrElement( + Handle::cast(target), name)); + + return *result; +} + + +// ES6 section 26.1.6 Reflect.get +BUILTIN(ReflectGet) { + HandleScope scope(isolate); + Handle undef = isolate->factory()->undefined_value(); + Handle target = args.length() > 1 ? args.at(1) : undef; + Handle key = args.length() > 2 ? args.at(2) : undef; + Handle receiver = args.length() > 3 ? args.at(3) : target; + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.get"))); + } + + Handle name; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, + Object::ToName(isolate, key)); + + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::GetPropertyOrElement( + Handle::cast(target), name, receiver)); + + return *result; +} + + +// ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor +BUILTIN(ReflectGetOwnPropertyDescriptor) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + Handle target = args.at(1); + Handle key = args.at(2); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.getOwnPropertyDescriptor"))); + } + + Handle name; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, + Object::ToName(isolate, key)); + + PropertyDescriptor desc; + bool found = JSReceiver::GetOwnPropertyDescriptor( + isolate, Handle::cast(target), name, &desc); + if (isolate->has_pending_exception()) return isolate->heap()->exception(); + if (!found) return isolate->heap()->undefined_value(); + return *desc.ToObject(isolate); +} + + +// ES6 section 26.1.8 Reflect.getPrototypeOf +BUILTIN(ReflectGetPrototypeOf) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + Handle target = args.at(1); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.getPrototypeOf"))); + } + + return *Object::GetPrototype(isolate, target); +} + + +// ES6 section 26.1.9 Reflect.has +BUILTIN(ReflectHas) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + Handle target = args.at(1); + Handle key = args.at(2); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.has"))); + } + + Handle name; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, + Object::ToName(isolate, key)); + + Maybe result = + JSReceiver::HasProperty(Handle::cast(target), name); + return result.IsJust() ? *isolate->factory()->ToBoolean(result.FromJust()) + : isolate->heap()->exception(); +} + + +// ES6 section 26.1.10 Reflect.isExtensible +BUILTIN(ReflectIsExtensible) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + Handle target = args.at(1); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.isExtensible"))); + } + + // TODO(neis): For now, we ignore proxies. Once proxies are fully + // implemented, do something like the following: + /* + Maybe maybe = JSReceiver::IsExtensible( + Handle::cast(target)); + if (!maybe.IsJust()) return isolate->heap()->exception(); + return *isolate->factory()->ToBoolean(maybe.FromJust()); + */ + + if (target->IsJSObject()) { + return *isolate->factory()->ToBoolean( + JSObject::IsExtensible(Handle::cast(target))); + } + return *isolate->factory()->false_value(); +} + + +// ES6 section 26.1.12 Reflect.preventExtensions +BUILTIN(ReflectPreventExtensions) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + Handle target = args.at(1); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.preventExtensions"))); + } + + Maybe result = JSReceiver::PreventExtensions( + Handle::cast(target), Object::DONT_THROW); + return result.IsJust() ? *isolate->factory()->ToBoolean(result.FromJust()) + : isolate->heap()->exception(); +} + + +// ES6 section 26.1.13 Reflect.set +BUILTIN(ReflectSet) { + HandleScope scope(isolate); + Handle undef = isolate->factory()->undefined_value(); + Handle target = args.length() > 1 ? args.at(1) : undef; + Handle key = args.length() > 2 ? args.at(2) : undef; + Handle value = args.length() > 3 ? args.at(3) : undef; + Handle receiver = args.length() > 4 ? args.at(4) : target; + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.set"))); + } + + Handle name; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, + Object::ToName(isolate, key)); + + LookupIterator it = LookupIterator::PropertyOrElement( + isolate, receiver, name, Handle::cast(target)); + Maybe result = Object::SetSuperProperty( + &it, value, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED); + MAYBE_RETURN(result, isolate->heap()->exception()); + return *isolate->factory()->ToBoolean(result.FromJust()); +} + + +// ES6 section 26.1.14 Reflect.setPrototypeOf +BUILTIN(ReflectSetPrototypeOf) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + Handle target = args.at(1); + Handle proto = args.at(2); + + if (!target->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, + isolate->factory()->NewStringFromAsciiChecked( + "Reflect.setPrototypeOf"))); + } + + if (!proto->IsJSReceiver() && !proto->IsNull()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); + } + + Maybe result = JSReceiver::SetPrototype( + Handle::cast(target), proto, true, Object::DONT_THROW); + MAYBE_RETURN(result, isolate->heap()->exception()); + return *isolate->factory()->ToBoolean(result.FromJust()); +} + + // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint ) BUILTIN(DateToPrimitive) { HandleScope scope(isolate); @@ -1536,7 +1803,7 @@ MUST_USE_RESULT static MaybeHandle HandleApiCallHelper( Handle receiver(&args[0]); if (receiver->IsJSObject() && receiver->IsAccessCheckNeeded()) { Handle js_receiver = Handle::cast(receiver); - if (!isolate->MayAccess(js_receiver)) { + if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { isolate->ReportFailedAccessCheck(js_receiver); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); } @@ -1611,6 +1878,34 @@ BUILTIN(HandleApiCallConstruct) { } +Handle Builtins::CallFunction(ConvertReceiverMode mode) { + switch (mode) { + case ConvertReceiverMode::kNullOrUndefined: + return CallFunction_ReceiverIsNullOrUndefined(); + case ConvertReceiverMode::kNotNullOrUndefined: + return CallFunction_ReceiverIsNotNullOrUndefined(); + case ConvertReceiverMode::kAny: + return CallFunction_ReceiverIsAny(); + } + UNREACHABLE(); + return Handle::null(); +} + + +Handle Builtins::Call(ConvertReceiverMode mode) { + switch (mode) { + case ConvertReceiverMode::kNullOrUndefined: + return Call_ReceiverIsNullOrUndefined(); + case ConvertReceiverMode::kNotNullOrUndefined: + return Call_ReceiverIsNotNullOrUndefined(); + case ConvertReceiverMode::kAny: + return Call_ReceiverIsAny(); + } + UNREACHABLE(); + return Handle::null(); +} + + namespace { class RelocatableArguments : public BuiltinArguments, diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h index d9129608dcca97..c1159a8d525284 100644 --- a/deps/v8/src/builtins.h +++ b/deps/v8/src/builtins.h @@ -59,6 +59,17 @@ enum BuiltinExtraArguments { \ V(DateToPrimitive, NO_EXTRA_ARGUMENTS) \ \ + V(ReflectDefineProperty, NO_EXTRA_ARGUMENTS) \ + V(ReflectDeleteProperty, NO_EXTRA_ARGUMENTS) \ + V(ReflectGet, NO_EXTRA_ARGUMENTS) \ + V(ReflectGetOwnPropertyDescriptor, NO_EXTRA_ARGUMENTS) \ + V(ReflectGetPrototypeOf, NO_EXTRA_ARGUMENTS) \ + V(ReflectHas, NO_EXTRA_ARGUMENTS) \ + V(ReflectIsExtensible, NO_EXTRA_ARGUMENTS) \ + V(ReflectPreventExtensions, NO_EXTRA_ARGUMENTS) \ + V(ReflectSet, NO_EXTRA_ARGUMENTS) \ + V(ReflectSetPrototypeOf, NO_EXTRA_ARGUMENTS) \ + \ V(SymbolConstructor, NO_EXTRA_ARGUMENTS) \ V(SymbolConstructor_ConstructStub, NO_EXTRA_ARGUMENTS) \ \ @@ -74,23 +85,26 @@ enum BuiltinExtraArguments { #define BUILTIN_LIST_A(V) \ V(ArgumentsAdaptorTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ \ - V(CallFunction, BUILTIN, UNINITIALIZED, kNoExtraICState) \ - V(Call, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(CallFunction_ReceiverIsNullOrUndefined, BUILTIN, UNINITIALIZED, \ + kNoExtraICState) \ + V(CallFunction_ReceiverIsNotNullOrUndefined, BUILTIN, UNINITIALIZED, \ + kNoExtraICState) \ + V(CallFunction_ReceiverIsAny, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(Call_ReceiverIsNullOrUndefined, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(Call_ReceiverIsNotNullOrUndefined, BUILTIN, UNINITIALIZED, \ + kNoExtraICState) \ + V(Call_ReceiverIsAny, BUILTIN, UNINITIALIZED, kNoExtraICState) \ \ V(ConstructFunction, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(ConstructProxy, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(Construct, BUILTIN, UNINITIALIZED, kNoExtraICState) \ \ - V(PushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \ - \ V(InOptimizationQueue, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(JSConstructStubGeneric, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(JSConstructStubForDerived, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(JSConstructStubApi, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(JSEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(JSConstructEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ - V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ - V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(CompileLazy, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(CompileOptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(CompileOptimizedConcurrent, BUILTIN, UNINITIALIZED, kNoExtraICState) \ @@ -100,6 +114,11 @@ enum BuiltinExtraArguments { V(NotifyStubFailure, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(NotifyStubFailureSaveDoubles, BUILTIN, UNINITIALIZED, kNoExtraICState) \ \ + V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterPushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterPushArgsAndConstruct, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + \ V(LoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(StoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ @@ -216,6 +235,10 @@ class Builtins { #undef DECLARE_BUILTIN_ACCESSOR_C #undef DECLARE_BUILTIN_ACCESSOR_A + // Convenience wrappers. + Handle CallFunction(ConvertReceiverMode = ConvertReceiverMode::kAny); + Handle Call(ConvertReceiverMode = ConvertReceiverMode::kAny); + Code* builtin(Name name) { // Code::cast cannot be used here since we access builtins // during the marking phase of mark sweep. See IC::Clear. @@ -266,8 +289,6 @@ class Builtins { static void Generate_JSConstructStubApi(MacroAssembler* masm); static void Generate_JSEntryTrampoline(MacroAssembler* masm); static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm); - static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm); - static void Generate_InterpreterExitTrampoline(MacroAssembler* masm); static void Generate_NotifyDeoptimized(MacroAssembler* masm); static void Generate_NotifySoftDeoptimized(MacroAssembler* masm); static void Generate_NotifyLazyDeoptimized(MacroAssembler* masm); @@ -276,9 +297,30 @@ class Builtins { static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm); // ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) - static void Generate_CallFunction(MacroAssembler* masm); + static void Generate_CallFunction(MacroAssembler* masm, + ConvertReceiverMode mode); + static void Generate_CallFunction_ReceiverIsNullOrUndefined( + MacroAssembler* masm) { + Generate_CallFunction(masm, ConvertReceiverMode::kNullOrUndefined); + } + static void Generate_CallFunction_ReceiverIsNotNullOrUndefined( + MacroAssembler* masm) { + Generate_CallFunction(masm, ConvertReceiverMode::kNotNullOrUndefined); + } + static void Generate_CallFunction_ReceiverIsAny(MacroAssembler* masm) { + Generate_CallFunction(masm, ConvertReceiverMode::kAny); + } // ES6 section 7.3.12 Call(F, V, [argumentsList]) - static void Generate_Call(MacroAssembler* masm); + static void Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode); + static void Generate_Call_ReceiverIsNullOrUndefined(MacroAssembler* masm) { + Generate_Call(masm, ConvertReceiverMode::kNullOrUndefined); + } + static void Generate_Call_ReceiverIsNotNullOrUndefined(MacroAssembler* masm) { + Generate_Call(masm, ConvertReceiverMode::kNotNullOrUndefined); + } + static void Generate_Call_ReceiverIsAny(MacroAssembler* masm) { + Generate_Call(masm, ConvertReceiverMode::kAny); + } // ES6 section 9.2.2 [[Construct]] ( argumentsList, newTarget) static void Generate_ConstructFunction(MacroAssembler* masm); @@ -287,8 +329,6 @@ class Builtins { // ES6 section 7.3.13 Construct (F, [argumentsList], [newTarget]) static void Generate_Construct(MacroAssembler* masm); - static void Generate_PushArgsAndCall(MacroAssembler* masm); - static void Generate_FunctionCall(MacroAssembler* masm); static void Generate_FunctionApply(MacroAssembler* masm); static void Generate_ReflectApply(MacroAssembler* masm); @@ -304,6 +344,11 @@ class Builtins { static void Generate_InterruptCheck(MacroAssembler* masm); static void Generate_StackCheck(MacroAssembler* masm); + static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm); + static void Generate_InterpreterExitTrampoline(MacroAssembler* masm); + static void Generate_InterpreterPushArgsAndCall(MacroAssembler* masm); + static void Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm); + #define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \ static void Generate_Make##C##CodeYoungAgainEvenMarking( \ MacroAssembler* masm); \ @@ -326,6 +371,7 @@ class Builtins { DISALLOW_COPY_AND_ASSIGN(Builtins); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_BUILTINS_H_ diff --git a/deps/v8/src/cached-powers.h b/deps/v8/src/cached-powers.h index bfe36351ba0cb6..fade5c9fcab2fe 100644 --- a/deps/v8/src/cached-powers.h +++ b/deps/v8/src/cached-powers.h @@ -37,6 +37,7 @@ class PowersOfTenCache { int* found_exponent); }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_CACHED_POWERS_H_ diff --git a/deps/v8/src/char-predicates-inl.h b/deps/v8/src/char-predicates-inl.h index d90f919341f6c2..ab5caa75573215 100644 --- a/deps/v8/src/char-predicates-inl.h +++ b/deps/v8/src/char-predicates-inl.h @@ -85,6 +85,7 @@ inline bool IsRegExpNewline(uc16 c) { } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_CHAR_PREDICATES_INL_H_ diff --git a/deps/v8/src/char-predicates.h b/deps/v8/src/char-predicates.h index 89f417196ef257..3161ae4ae930c4 100644 --- a/deps/v8/src/char-predicates.h +++ b/deps/v8/src/char-predicates.h @@ -79,6 +79,7 @@ struct WhiteSpaceOrLineTerminator { } }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_CHAR_PREDICATES_H_ diff --git a/deps/v8/src/checks.h b/deps/v8/src/checks.h index bd798663ad250a..80404e8d89710e 100644 --- a/deps/v8/src/checks.h +++ b/deps/v8/src/checks.h @@ -23,7 +23,8 @@ extern bool FLAG_enable_slow_asserts; const bool FLAG_enable_slow_asserts = false; #endif -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #define DCHECK_TAG_ALIGNED(address) \ DCHECK((reinterpret_cast(address) & \ diff --git a/deps/v8/src/code-factory.cc b/deps/v8/src/code-factory.cc index 9e776b40fc5ea1..ad6890bf2295ff 100644 --- a/deps/v8/src/code-factory.cc +++ b/deps/v8/src/code-factory.cc @@ -59,17 +59,17 @@ Callable CodeFactory::KeyedLoadICInOptimizedCode( // static Callable CodeFactory::CallIC(Isolate* isolate, int argc, - CallICState::CallType call_type) { - return Callable(CallIC::initialize_stub(isolate, argc, call_type), + ConvertReceiverMode mode) { + return Callable(CallIC::initialize_stub(isolate, argc, mode), CallFunctionWithFeedbackDescriptor(isolate)); } // static Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc, - CallICState::CallType call_type) { + ConvertReceiverMode mode) { return Callable( - CallIC::initialize_stub_in_optimized_code(isolate, argc, call_type), + CallIC::initialize_stub_in_optimized_code(isolate, argc, mode), CallFunctionWithFeedbackAndVectorDescriptor(isolate)); } @@ -130,24 +130,16 @@ Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op, // static -Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op, - Strength strength) { - BinaryOpICStub stub(isolate, op, strength); - return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +Callable CodeFactory::CompareNilIC(Isolate* isolate, NilValue nil_value) { + Handle code = CompareNilICStub::GetUninitialized(isolate, nil_value); + return Callable(code, CompareNilDescriptor(isolate)); } // static -Callable CodeFactory::LoadGlobalViaContext(Isolate* isolate, int depth) { - LoadGlobalViaContextStub stub(isolate, depth); - return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); -} - - -// static -Callable CodeFactory::StoreGlobalViaContext(Isolate* isolate, int depth, - LanguageMode language_mode) { - StoreGlobalViaContextStub stub(isolate, depth, language_mode); +Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op, + Strength strength) { + BinaryOpICStub stub(isolate, op, strength); return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); } @@ -182,6 +174,13 @@ Callable CodeFactory::ToString(Isolate* isolate) { } +// static +Callable CodeFactory::ToLength(Isolate* isolate) { + ToLengthStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + + // static Callable CodeFactory::ToObject(Isolate* isolate) { ToObjectStub stub(isolate); @@ -189,6 +188,20 @@ Callable CodeFactory::ToObject(Isolate* isolate) { } +// static +Callable CodeFactory::NumberToString(Isolate* isolate) { + NumberToStringStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + + +// static +Callable CodeFactory::RegExpConstructResult(Isolate* isolate) { + RegExpConstructResultStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + + // static Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags, PretenureFlag pretenure_flag) { @@ -226,6 +239,13 @@ Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) { } +// static +Callable CodeFactory::FastNewContext(Isolate* isolate, int slot_count) { + FastNewContextStub stub(isolate, slot_count); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + + // static Callable CodeFactory::FastNewClosure(Isolate* isolate, LanguageMode language_mode, @@ -254,17 +274,61 @@ Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) { // static -Callable CodeFactory::CallFunction(Isolate* isolate, int argc, - CallFunctionFlags flags) { - CallFunctionStub stub(isolate, argc, flags); +Callable CodeFactory::AllocateMutableHeapNumber(Isolate* isolate) { + AllocateMutableHeapNumberStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + + +// static +Callable CodeFactory::AllocateInNewSpace(Isolate* isolate) { + AllocateInNewSpaceStub stub(isolate); return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); } // static -Callable CodeFactory::PushArgsAndCall(Isolate* isolate) { - return Callable(isolate->builtins()->PushArgsAndCall(), - PushArgsAndCallDescriptor(isolate)); +Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) { + return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(), + ArgumentAdaptorDescriptor(isolate)); +} + + +// static +Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode) { + return Callable(isolate->builtins()->Call(mode), + CallTrampolineDescriptor(isolate)); +} + + +// static +Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) { + return Callable(isolate->builtins()->CallFunction(mode), + CallTrampolineDescriptor(isolate)); +} + + +// static +Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate) { + return Callable(isolate->builtins()->InterpreterPushArgsAndCall(), + InterpreterPushArgsAndCallDescriptor(isolate)); +} + + +// static +Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) { + return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(), + InterpreterPushArgsAndConstructDescriptor(isolate)); +} + + +// static +Callable CodeFactory::InterpreterCEntry(Isolate* isolate) { + // TODO(rmcilroy): Deal with runtime functions that return two values. + // Note: If we ever use fpregs in the interpreter then we will need to + // save fpregs too. + CEntryStub stub(isolate, 1, kDontSaveFPRegs, kArgvInRegister); + return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate)); } } // namespace internal diff --git a/deps/v8/src/code-factory.h b/deps/v8/src/code-factory.h index 5a67b27fd54b07..4775efeb89a0f2 100644 --- a/deps/v8/src/code-factory.h +++ b/deps/v8/src/code-factory.h @@ -43,9 +43,10 @@ class CodeFactory final { Isolate* isolate, LanguageMode language_mode, InlineCacheState initialization_state); static Callable CallIC(Isolate* isolate, int argc, - CallICState::CallType call_type); - static Callable CallICInOptimizedCode(Isolate* isolate, int argc, - CallICState::CallType call_type); + ConvertReceiverMode mode = ConvertReceiverMode::kAny); + static Callable CallICInOptimizedCode( + Isolate* isolate, int argc, + ConvertReceiverMode mode = ConvertReceiverMode::kAny); static Callable StoreIC(Isolate* isolate, LanguageMode mode); static Callable StoreICInOptimizedCode(Isolate* isolate, LanguageMode mode, InlineCacheState initialization_state); @@ -56,16 +57,13 @@ class CodeFactory final { static Callable CompareIC(Isolate* isolate, Token::Value op, Strength strength); + static Callable CompareNilIC(Isolate* isolate, NilValue nil_value); static Callable BinaryOpIC(Isolate* isolate, Token::Value op, Strength strength); // Code stubs. Add methods here as needed to reduce dependency on // code-stubs.h. - static Callable LoadGlobalViaContext(Isolate* isolate, int depth); - static Callable StoreGlobalViaContext(Isolate* isolate, int depth, - LanguageMode language_mode); - static Callable InstanceOf(Isolate* isolate); static Callable ToBoolean( @@ -74,7 +72,11 @@ class CodeFactory final { static Callable ToNumber(Isolate* isolate); static Callable ToString(Isolate* isolate); + static Callable ToLength(Isolate* isolate); static Callable ToObject(Isolate* isolate); + static Callable NumberToString(Isolate* isolate); + + static Callable RegExpConstructResult(Isolate* isolate); static Callable StringAdd(Isolate* isolate, StringAddFlags flags, PretenureFlag pretenure_flag); @@ -85,6 +87,7 @@ class CodeFactory final { static Callable FastCloneShallowArray(Isolate* isolate); static Callable FastCloneShallowObject(Isolate* isolate, int length); + static Callable FastNewContext(Isolate* isolate, int slot_count); static Callable FastNewClosure(Isolate* isolate, LanguageMode language_mode, FunctionKind kind); @@ -92,11 +95,18 @@ class CodeFactory final { bool has_duplicate_parameters); static Callable AllocateHeapNumber(Isolate* isolate); - - static Callable CallFunction(Isolate* isolate, int argc, - CallFunctionFlags flags); - - static Callable PushArgsAndCall(Isolate* isolate); + static Callable AllocateMutableHeapNumber(Isolate* isolate); + static Callable AllocateInNewSpace(Isolate* isolate); + + static Callable ArgumentAdaptor(Isolate* isolate); + static Callable Call(Isolate* isolate, + ConvertReceiverMode mode = ConvertReceiverMode::kAny); + static Callable CallFunction( + Isolate* isolate, ConvertReceiverMode mode = ConvertReceiverMode::kAny); + + static Callable InterpreterPushArgsAndCall(Isolate* isolate); + static Callable InterpreterPushArgsAndConstruct(Isolate* isolate); + static Callable InterpreterCEntry(Isolate* isolate); }; } // namespace internal diff --git a/deps/v8/src/code-stubs-hydrogen.cc b/deps/v8/src/code-stubs-hydrogen.cc index 801079bcd9473c..b2d07d9c9b9415 100644 --- a/deps/v8/src/code-stubs-hydrogen.cc +++ b/deps/v8/src/code-stubs-hydrogen.cc @@ -5,10 +5,10 @@ #include "src/code-stubs.h" #include "src/bailout-reason.h" +#include "src/crankshaft/hydrogen.h" +#include "src/crankshaft/lithium.h" #include "src/field-index.h" -#include "src/hydrogen.h" #include "src/ic/ic.h" -#include "src/lithium.h" namespace v8 { namespace internal { @@ -442,7 +442,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { info()->MarkMustNotHaveEagerFrame(); HInstruction* allocation_site = Add( - GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS, + GetParameter(0), GetParameter(1), nullptr, nullptr, FAST_ELEMENTS, NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); IfBuilder checker(this); checker.IfNot(allocation_site, @@ -505,7 +505,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HValue* undefined = graph()->GetConstantUndefined(); HInstruction* allocation_site = Add( - GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS, + GetParameter(0), GetParameter(1), nullptr, nullptr, FAST_ELEMENTS, NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); IfBuilder checker(this); @@ -635,7 +635,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* feedback_vector = GetParameter(0); HInstruction* slot = GetParameter(1); - Add(feedback_vector, slot, object, FAST_ELEMENTS, + Add(feedback_vector, slot, object, nullptr, FAST_ELEMENTS, INITIALIZING_STORE); return feedback_vector; } @@ -667,7 +667,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* feedback_vector = GetParameter(CreateWeakCellDescriptor::kVectorIndex); HInstruction* slot = GetParameter(CreateWeakCellDescriptor::kSlotIndex); - Add(feedback_vector, slot, object, FAST_ELEMENTS, + Add(feedback_vector, slot, object, nullptr, FAST_ELEMENTS, INITIALIZING_STORE); return graph()->GetConstant0(); } @@ -823,8 +823,8 @@ HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key, HValue* value) { HValue* result = NULL; HInstruction* backing_store = - Add(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS, - ALLOW_RETURN_HOLE); + Add(elements, graph()->GetConstant1(), nullptr, nullptr, + FAST_ELEMENTS, ALLOW_RETURN_HOLE); Add(backing_store, isolate()->factory()->fixed_array_map()); HValue* backing_store_length = Add( backing_store, nullptr, HObjectAccess::ForFixedArrayLength()); @@ -834,10 +834,10 @@ HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key, in_unmapped_range.Then(); { if (value == NULL) { - result = Add(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, - NEVER_RETURN_HOLE); + result = Add(backing_store, key, nullptr, nullptr, + FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE); } else { - Add(backing_store, key, value, FAST_HOLEY_ELEMENTS); + Add(backing_store, key, value, nullptr, FAST_HOLEY_ELEMENTS); } } in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange); @@ -894,8 +894,9 @@ HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver, in_range.Then(); { HValue* index = AddUncasted(key, constant_two); - HInstruction* mapped_index = Add( - elements, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); + HInstruction* mapped_index = + Add(elements, index, nullptr, nullptr, FAST_HOLEY_ELEMENTS, + ALLOW_RETURN_HOLE); IfBuilder is_valid(this); is_valid.IfNot(mapped_index, @@ -906,15 +907,17 @@ HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver, // mapped_index is not the hole that it is indeed, a smi. An unnecessary // smi check is being emitted. HValue* the_context = Add(elements, graph()->GetConstant0(), - nullptr, FAST_ELEMENTS); + nullptr, nullptr, FAST_ELEMENTS); STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); if (is_load) { - HValue* result = Add(the_context, mapped_index, nullptr, - FAST_ELEMENTS, ALLOW_RETURN_HOLE); + HValue* result = + Add(the_context, mapped_index, nullptr, nullptr, + FAST_ELEMENTS, ALLOW_RETURN_HOLE); environment()->Push(result); } else { DCHECK(value != NULL); - Add(the_context, mapped_index, value, FAST_ELEMENTS); + Add(the_context, mapped_index, value, nullptr, + FAST_ELEMENTS); environment()->Push(value); } } @@ -1139,6 +1142,34 @@ Handle AllocateHeapNumberStub::GenerateCode() { } +template <> +HValue* CodeStubGraphBuilder::BuildCodeStub() { + HValue* result = + Add(Add(HeapNumber::kSize), HType::HeapObject(), + NOT_TENURED, MUTABLE_HEAP_NUMBER_TYPE); + AddStoreMapConstant(result, isolate()->factory()->mutable_heap_number_map()); + return result; +} + + +Handle AllocateMutableHeapNumberStub::GenerateCode() { + return DoGenerateCode(this); +} + + +template <> +HValue* CodeStubGraphBuilder::BuildCodeStub() { + HValue* result = Add(GetParameter(0), HType::Tagged(), NOT_TENURED, + JS_OBJECT_TYPE); + return result; +} + + +Handle AllocateInNewSpaceStub::GenerateCode() { + return DoGenerateCode(this); +} + + HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( ElementsKind kind, AllocationSiteOverrideMode override_mode, @@ -1214,7 +1245,7 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor( // trigger it. HValue* length = GetArgumentsLength(); HConstant* max_alloc_length = - Add(JSObject::kInitialMaxFastElementArray); + Add(JSArray::kInitialMaxFastElementArray); HValue* checked_length = Add(length, max_alloc_length); // We need to fill with the hole if it's a smi array in the multi-argument @@ -1245,7 +1276,7 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor( HInstruction* argument = Add( argument_elements, checked_length, key); - Add(elements, key, argument, kind); + Add(elements, key, argument, nullptr, kind); builder.EndBody(); return new_object; } @@ -1342,12 +1373,11 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { if_nil.Then(); if (continuation.IsFalseReachable()) { if_nil.Else(); - if_nil.Return(graph()->GetConstant0()); + if_nil.Return(graph()->GetConstantFalse()); } if_nil.End(); - return continuation.IsTrueReachable() - ? graph()->GetConstant1() - : graph()->GetConstantUndefined(); + return continuation.IsTrueReachable() ? graph()->GetConstantTrue() + : graph()->GetConstantUndefined(); } @@ -1877,8 +1907,8 @@ HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap( HValue* field_offset_value = Add(field_offset); field_slot = AddUncasted(iterator, field_offset_value); } - HInstruction* field_entry = - Add(optimized_map, field_slot, nullptr, FAST_ELEMENTS); + HInstruction* field_entry = Add(optimized_map, field_slot, + nullptr, nullptr, FAST_ELEMENTS); return field_entry; } @@ -2298,13 +2328,13 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { Add(probe_base + KeyedLookupCache::kKeyIndex)); key_index->ClearFlag(HValue::kCanOverflow); HValue* map_to_check = - Add(cache_keys, map_index, nullptr, FAST_ELEMENTS, - NEVER_RETURN_HOLE, 0); + Add(cache_keys, map_index, nullptr, nullptr, + FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); lookup_if->If(map_to_check, map); lookup_if->And(); HValue* key_to_check = - Add(cache_keys, key_index, nullptr, FAST_ELEMENTS, - NEVER_RETURN_HOLE, 0); + Add(cache_keys, key_index, nullptr, nullptr, + FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); lookup_if->If(key_to_check, key); lookup_if->Then(); { @@ -2315,7 +2345,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HValue* index = AddUncasted(hash, Add(probe)); index->ClearFlag(HValue::kCanOverflow); HValue* property_index = - Add(cache_field_offsets, index, nullptr, + Add(cache_field_offsets, index, nullptr, cache_keys, INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); Push(property_index); } diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc index 5c8c763a3a94d8..61df12781b119c 100644 --- a/deps/v8/src/code-stubs.cc +++ b/deps/v8/src/code-stubs.cc @@ -744,6 +744,18 @@ void AllocateHeapNumberStub::InitializeDescriptor( } +void AllocateMutableHeapNumberStub::InitializeDescriptor( + CodeStubDescriptor* descriptor) { + descriptor->Initialize(); +} + + +void AllocateInNewSpaceStub::InitializeDescriptor( + CodeStubDescriptor* descriptor) { + descriptor->Initialize(); +} + + void CompareNilICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { descriptor->Initialize(FUNCTION_ADDR(Runtime_CompareNilIC_Miss)); descriptor->SetMissHandler(ExternalReference( @@ -881,11 +893,6 @@ void ArgumentsAccessStub::PrintName(std::ostream& os) const { // NOLINT } -void CallFunctionStub::PrintName(std::ostream& os) const { // NOLINT - os << "CallFunctionStub_Args" << argc(); -} - - void CallConstructStub::PrintName(std::ostream& os) const { // NOLINT os << "CallConstructStub"; if (RecordCallTarget()) os << "_Recording"; @@ -1049,7 +1056,7 @@ InternalArrayConstructorStub::InternalArrayConstructorStub( Representation RepresentationFromType(Type* type) { - if (type->Is(Type::UntaggedSigned()) || type->Is(Type::UntaggedUnsigned())) { + if (type->Is(Type::UntaggedIntegral())) { return Representation::Integer32(); } @@ -1064,5 +1071,6 @@ Representation RepresentationFromType(Type* type) { DCHECK(!type->Is(Type::Untagged())); return Representation::Tagged(); } + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h index 163fdd88086208..d69e9263e14a12 100644 --- a/deps/v8/src/code-stubs.h +++ b/deps/v8/src/code-stubs.h @@ -27,7 +27,6 @@ namespace internal { V(CallApiAccessor) \ V(CallApiGetter) \ V(CallConstruct) \ - V(CallFunction) \ V(CallIC) \ V(CEntry) \ V(CompareIC) \ @@ -52,6 +51,7 @@ namespace internal { V(StubFailureTrampoline) \ V(SubString) \ V(ToNumber) \ + V(ToLength) \ V(ToString) \ V(ToObject) \ V(VectorStoreICTrampoline) \ @@ -60,6 +60,8 @@ namespace internal { V(VectorKeyedStoreIC) \ /* HydrogenCodeStubs */ \ V(AllocateHeapNumber) \ + V(AllocateMutableHeapNumber) \ + V(AllocateInNewSpace) \ V(ArrayNArgumentsConstructor) \ V(ArrayNoArgumentConstructor) \ V(ArraySingleArgumentConstructor) \ @@ -539,7 +541,7 @@ class TurboFanCodeStub : public CodeStub { // Retrieve the code for the stub. Generate the code if needed. Handle GenerateCode() override; - virtual int GetStackParameterCount() const override { + int GetStackParameterCount() const override { return GetCallInterfaceDescriptor().GetStackParameterCount(); } @@ -597,7 +599,8 @@ class RuntimeCallHelper { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #if V8_TARGET_ARCH_IA32 #include "src/ia32/code-stubs-ia32.h" @@ -629,9 +632,9 @@ class StubRuntimeCallHelper : public RuntimeCallHelper { public: StubRuntimeCallHelper() {} - virtual void BeforeCall(MacroAssembler* masm) const; + void BeforeCall(MacroAssembler* masm) const override; - virtual void AfterCall(MacroAssembler* masm) const; + void AfterCall(MacroAssembler* masm) const override; }; @@ -640,9 +643,9 @@ class NopRuntimeCallHelper : public RuntimeCallHelper { public: NopRuntimeCallHelper() {} - virtual void BeforeCall(MacroAssembler* masm) const {} + void BeforeCall(MacroAssembler* masm) const override {} - virtual void AfterCall(MacroAssembler* masm) const {} + void AfterCall(MacroAssembler* masm) const override {} }; @@ -972,18 +975,14 @@ class CallICStub: public PlatformCodeStub { Code::Kind GetCodeKind() const override { return Code::CALL_IC; } - InlineCacheState GetICState() const override { return DEFAULT; } + InlineCacheState GetICState() const override { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); } protected: - bool CallAsMethod() const { - return state().call_type() == CallICState::METHOD; - } - - int arg_count() const { return state().arg_count(); } + int arg_count() const { return state().argc(); } CallICState state() const { return CallICState(static_cast(minor_key_)); @@ -1243,8 +1242,10 @@ class StoreTransitionHelper { } static Register MapRegister() { - return FLAG_vector_stores ? VectorStoreTransitionDescriptor::MapRegister() - : StoreTransitionDescriptor::MapRegister(); + if (FLAG_vector_stores) { + return VectorStoreTransitionDescriptor::MapRegister(); + } + return StoreTransitionDescriptor::MapRegister(); } static int ReceiverIndex() { @@ -1255,26 +1256,25 @@ class StoreTransitionHelper { static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; } - static int SlotIndex() { - DCHECK(FLAG_vector_stores); - return VectorStoreTransitionDescriptor::kSlotIndex; + static int MapIndex() { + DCHECK(static_cast(VectorStoreTransitionDescriptor::kMapIndex) == + static_cast(StoreTransitionDescriptor::kMapIndex)); + return StoreTransitionDescriptor::kMapIndex; } static int VectorIndex() { DCHECK(FLAG_vector_stores); + if (HasVirtualSlotArg()) { + return VectorStoreTransitionDescriptor::kVirtualSlotVectorIndex; + } return VectorStoreTransitionDescriptor::kVectorIndex; } - static int MapIndex() { - if (FLAG_vector_stores) { - return VectorStoreTransitionDescriptor::kMapIndex; - } - return StoreTransitionDescriptor::kMapIndex; + // Some platforms don't have a slot arg. + static bool HasVirtualSlotArg() { + if (!FLAG_vector_stores) return false; + return SlotRegister().is(no_reg); } - - // Some platforms push Slot, Vector, Map on the stack instead of in - // registers. - static bool UsesStackArgs() { return MapRegister().is(no_reg); } }; @@ -1353,7 +1353,7 @@ class StoreGlobalStub : public HandlerStub { return isolate->factory()->termination_exception(); } - Handle GetCodeCopyFromTemplate(Handle global, + Handle GetCodeCopyFromTemplate(Handle global, Handle cell) { Code::FindAndReplacePattern pattern; if (check_global()) { @@ -1823,9 +1823,11 @@ std::ostream& operator<<(std::ostream& os, const CompareNilICStub::State& s); class CEntryStub : public PlatformCodeStub { public: CEntryStub(Isolate* isolate, int result_size, - SaveFPRegsMode save_doubles = kDontSaveFPRegs) + SaveFPRegsMode save_doubles = kDontSaveFPRegs, + ArgvMode argv_mode = kArgvOnStack) : PlatformCodeStub(isolate) { - minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs); + minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs) | + ArgvMode::encode(argv_mode == kArgvInRegister); DCHECK(result_size == 1 || result_size == 2); #if _WIN64 || V8_TARGET_ARCH_PPC minor_key_ = ResultSizeBits::update(minor_key_, result_size); @@ -1840,6 +1842,7 @@ class CEntryStub : public PlatformCodeStub { private: bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); } + bool argv_in_register() const { return ArgvMode::decode(minor_key_); } #if _WIN64 || V8_TARGET_ARCH_PPC int result_size() const { return ResultSizeBits::decode(minor_key_); } #endif // _WIN64 @@ -1847,7 +1850,8 @@ class CEntryStub : public PlatformCodeStub { bool NeedsImmovableCode() override; class SaveDoublesBits : public BitField {}; - class ResultSizeBits : public BitField {}; + class ArgvMode : public BitField {}; + class ResultSizeBits : public BitField {}; DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub); @@ -1954,38 +1958,6 @@ class RegExpConstructResultStub final : public HydrogenCodeStub { }; -// TODO(bmeurer): Deprecate the CallFunctionStub in favor of the more general -// Invoke family of builtins. -class CallFunctionStub: public PlatformCodeStub { - public: - CallFunctionStub(Isolate* isolate, int argc, CallFunctionFlags flags) - : PlatformCodeStub(isolate) { - DCHECK(argc >= 0 && argc <= Code::kMaxArguments); - minor_key_ = ArgcBits::encode(argc) | FlagBits::encode(flags); - } - - private: - int argc() const { return ArgcBits::decode(minor_key_); } - int flags() const { return FlagBits::decode(minor_key_); } - - bool CallAsMethod() const { - return flags() == CALL_AS_METHOD || flags() == WRAP_AND_CALL; - } - - bool NeedsChecks() const { return flags() != WRAP_AND_CALL; } - - void PrintName(std::ostream& os) const override; // NOLINT - - // Minor key encoding in 32 bits with Bitfield . - class FlagBits : public BitField {}; - class ArgcBits : public BitField {}; - STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits); - - DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction); - DEFINE_PLATFORM_CODE_STUB(CallFunction, PlatformCodeStub); -}; - - class CallConstructStub: public PlatformCodeStub { public: CallConstructStub(Isolate* isolate, CallConstructorFlags flags) @@ -2250,7 +2222,7 @@ class LoadICTrampolineStub : public PlatformCodeStub { Code::Kind GetCodeKind() const override { return Code::LOAD_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } + InlineCacheState GetICState() const final { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); @@ -2286,7 +2258,7 @@ class VectorStoreICTrampolineStub : public PlatformCodeStub { Code::Kind GetCodeKind() const override { return Code::STORE_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } + InlineCacheState GetICState() const final { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); @@ -2324,7 +2296,7 @@ class CallICTrampolineStub : public PlatformCodeStub { Code::Kind GetCodeKind() const override { return Code::CALL_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } + InlineCacheState GetICState() const final { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); @@ -2350,7 +2322,7 @@ class LoadICStub : public PlatformCodeStub { void GenerateForTrampoline(MacroAssembler* masm); Code::Kind GetCodeKind() const override { return Code::LOAD_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } + InlineCacheState GetICState() const final { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); } @@ -2373,7 +2345,7 @@ class KeyedLoadICStub : public PlatformCodeStub { void GenerateForTrampoline(MacroAssembler* masm); Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } + InlineCacheState GetICState() const final { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); } @@ -2396,7 +2368,7 @@ class VectorStoreICStub : public PlatformCodeStub { void GenerateForTrampoline(MacroAssembler* masm); Code::Kind GetCodeKind() const final { return Code::STORE_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } + InlineCacheState GetICState() const final { return GENERIC; } ExtraICState GetExtraICState() const final { return static_cast(minor_key_); } @@ -2419,8 +2391,8 @@ class VectorKeyedStoreICStub : public PlatformCodeStub { void GenerateForTrampoline(MacroAssembler* masm); Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; } - InlineCacheState GetICState() const final { return DEFAULT; } - virtual ExtraICState GetExtraICState() const final { + InlineCacheState GetICState() const final { return GENERIC; } + ExtraICState GetExtraICState() const final { return static_cast(minor_key_); } @@ -2650,6 +2622,28 @@ class AllocateHeapNumberStub final : public HydrogenCodeStub { }; +class AllocateMutableHeapNumberStub final : public HydrogenCodeStub { + public: + explicit AllocateMutableHeapNumberStub(Isolate* isolate) + : HydrogenCodeStub(isolate) {} + + private: + DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateMutableHeapNumber); + DEFINE_HYDROGEN_CODE_STUB(AllocateMutableHeapNumber, HydrogenCodeStub); +}; + + +class AllocateInNewSpaceStub final : public HydrogenCodeStub { + public: + explicit AllocateInNewSpaceStub(Isolate* isolate) + : HydrogenCodeStub(isolate) {} + + private: + DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateInNewSpace); + DEFINE_HYDROGEN_CODE_STUB(AllocateInNewSpace, HydrogenCodeStub); +}; + + class ArrayConstructorStubBase : public HydrogenCodeStub { public: ArrayConstructorStubBase(Isolate* isolate, @@ -3058,6 +3052,15 @@ class ToNumberStub final : public PlatformCodeStub { }; +class ToLengthStub final : public PlatformCodeStub { + public: + explicit ToLengthStub(Isolate* isolate) : PlatformCodeStub(isolate) {} + + DEFINE_CALL_INTERFACE_DESCRIPTOR(ToLength); + DEFINE_PLATFORM_CODE_STUB(ToLength, PlatformCodeStub); +}; + + class ToStringStub final : public PlatformCodeStub { public: explicit ToStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {} diff --git a/deps/v8/src/codegen.cc b/deps/v8/src/codegen.cc index fd039d0f8a4ca5..1e806d2ae53da0 100644 --- a/deps/v8/src/codegen.cc +++ b/deps/v8/src/codegen.cc @@ -122,19 +122,19 @@ void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) { if (FLAG_trace_codegen || print_source || print_ast) { base::SmartArrayPointer name = info->GetDebugName(); - PrintF("[generating %s code for %s function: %s]", kind, ftype, name.get()); + PrintF("[generating %s code for %s function: %s]\n", kind, ftype, + name.get()); } #ifdef DEBUG if (info->parse_info() && print_source) { PrintF("--- Source from AST ---\n%s\n", - PrettyPrinter(info->isolate(), info->zone()) - .PrintProgram(info->literal())); + PrettyPrinter(info->isolate()).PrintProgram(info->literal())); } if (info->parse_info() && print_ast) { - PrintF("--- AST ---\n%s\n", AstPrinter(info->isolate(), info->zone()) - .PrintProgram(info->literal())); + PrintF("--- AST ---\n%s\n", + AstPrinter(info->isolate()).PrintProgram(info->literal())); } #endif // DEBUG } diff --git a/deps/v8/src/codegen.h b/deps/v8/src/codegen.h index 04f130999eec30..7019d3d106e738 100644 --- a/deps/v8/src/codegen.h +++ b/deps/v8/src/codegen.h @@ -170,6 +170,7 @@ class CodeAgingHelper { #endif }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_CODEGEN_H_ diff --git a/deps/v8/src/compilation-cache.h b/deps/v8/src/compilation-cache.h index 2d7609ec1876ff..2295f4c6855495 100644 --- a/deps/v8/src/compilation-cache.h +++ b/deps/v8/src/compilation-cache.h @@ -236,6 +236,7 @@ class CompilationCache { }; -} } // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_COMPILATION_CACHE_H_ diff --git a/deps/v8/src/compilation-dependencies.cc b/deps/v8/src/compilation-dependencies.cc index 643b88ab0ec087..c9c194f19ff056 100644 --- a/deps/v8/src/compilation-dependencies.cc +++ b/deps/v8/src/compilation-dependencies.cc @@ -106,6 +106,24 @@ void CompilationDependencies::Rollback() { } +void CompilationDependencies::AssumeMapNotDeprecated(Handle map) { + DCHECK(!map->is_deprecated()); + // Do nothing if the map cannot be deprecated. + if (map->CanBeDeprecated()) { + Insert(DependentCode::kTransitionGroup, map); + } +} + + +void CompilationDependencies::AssumeMapStable(Handle map) { + DCHECK(map->is_stable()); + // Do nothing if the map cannot transition. + if (map->CanTransition()) { + Insert(DependentCode::kPrototypeCheckGroup, map); + } +} + + void CompilationDependencies::AssumeTransitionStable( Handle site) { // Do nothing if the object doesn't have any useful element transitions left. diff --git a/deps/v8/src/compilation-dependencies.h b/deps/v8/src/compilation-dependencies.h index c14220880f1f07..ca09ef5e116a82 100644 --- a/deps/v8/src/compilation-dependencies.h +++ b/deps/v8/src/compilation-dependencies.h @@ -31,6 +31,8 @@ class CompilationDependencies { void AssumeFieldType(Handle map) { Insert(DependentCode::kFieldTypeGroup, map); } + void AssumeMapStable(Handle map); + void AssumeMapNotDeprecated(Handle map); void AssumePropertyCell(Handle cell) { Insert(DependentCode::kPropertyCellChangedGroup, cell); } @@ -61,7 +63,7 @@ class CompilationDependencies { DependentCode* Get(Handle object); void Set(Handle object, Handle dep); }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_DEPENDENCIES_H_ diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 20aa558c3d1e31..d55bf33babca94 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -11,15 +11,16 @@ #include "src/codegen.h" #include "src/compilation-cache.h" #include "src/compiler/pipeline.h" +#include "src/crankshaft/hydrogen.h" +#include "src/crankshaft/lithium.h" +#include "src/crankshaft/typing.h" #include "src/debug/debug.h" #include "src/debug/liveedit.h" #include "src/deoptimizer.h" #include "src/full-codegen/full-codegen.h" #include "src/gdb-jit.h" -#include "src/hydrogen.h" #include "src/interpreter/interpreter.h" #include "src/isolate-inl.h" -#include "src/lithium.h" #include "src/log-inl.h" #include "src/messages.h" #include "src/parser.h" @@ -31,7 +32,6 @@ #include "src/scopeinfo.h" #include "src/scopes.h" #include "src/snapshot/serialize.h" -#include "src/typing.h" #include "src/vm-state-inl.h" namespace v8 { @@ -172,9 +172,6 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, dependencies_(isolate, zone), bailout_reason_(kNoReason), prologue_offset_(Code::kPrologueOffsetNotSet), - no_frame_ranges_(isolate->cpu_profiler()->is_profiling() - ? new List(2) - : nullptr), track_positions_(FLAG_hydrogen_track_positions || isolate->cpu_profiler()->is_profiling()), opt_count_(has_shared_info() ? shared_info()->opt_count() : 0), @@ -200,7 +197,6 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, CompilationInfo::~CompilationInfo() { DisableFutureOptimization(); delete deferred_handles_; - delete no_frame_ranges_; #ifdef DEBUG // Check that no dependent maps have been added or added dependent maps have // been rolled back or committed. @@ -249,13 +245,15 @@ bool CompilationInfo::ShouldSelfOptimize() { void CompilationInfo::EnsureFeedbackVector() { if (feedback_vector_.is_null()) { - feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( - literal()->feedback_vector_spec()); + Handle feedback_metadata = + TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); + feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata); } // It's very important that recompiles do not alter the structure of the // type feedback vector. - CHECK(!feedback_vector_->SpecDiffersFrom(literal()->feedback_vector_spec())); + CHECK(!feedback_vector_->metadata()->SpecDiffersFrom( + literal()->feedback_vector_spec())); } @@ -330,9 +328,8 @@ base::SmartArrayPointer CompilationInfo::GetDebugName() const { } -bool CompilationInfo::MustReplaceUndefinedReceiverWithGlobalProxy() { - return is_sloppy(language_mode()) && !is_native() && - scope()->has_this_declaration() && scope()->receiver()->is_used(); +bool CompilationInfo::ExpectsJSReceiverAsReceiver() { + return is_sloppy(language_mode()) && !is_native(); } @@ -441,9 +438,10 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { if (info()->shared_info()->asm_function()) { if (info()->osr_frame()) info()->MarkAsFrameSpecializing(); info()->MarkAsFunctionContextSpecializing(); - } else if (FLAG_turbo_type_feedback) { - info()->MarkAsTypeFeedbackEnabled(); - info()->EnsureFeedbackVector(); + } else if (info()->has_global_object() && + FLAG_native_context_specialization) { + info()->MarkAsNativeContextSpecializing(); + info()->MarkAsTypingEnabled(); } if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { @@ -705,15 +703,37 @@ static bool CompileUnoptimizedCode(CompilationInfo* info) { } +// TODO(rmcilroy): Remove this temporary work-around when ignition supports +// catch and eval. +static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) { + if (!FLAG_ignition_fallback_on_eval_and_catch) return false; + + if (scope->is_eval_scope() || scope->is_catch_scope() || + scope->calls_eval()) { + return true; + } + for (auto inner_scope : *scope->inner_scopes()) { + if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true; + } + return false; +} + + static bool GenerateBytecode(CompilationInfo* info) { DCHECK(AllowCompilation::IsAllowed(info->isolate())); - if (!Compiler::Analyze(info->parse_info()) || - !interpreter::Interpreter::MakeBytecode(info)) { + bool success = false; + if (Compiler::Analyze(info->parse_info())) { + if (IgnitionShouldFallbackToFullCodeGen(info->scope())) { + success = FullCodeGenerator::MakeCode(info); + } else { + success = interpreter::Interpreter::MakeBytecode(info); + } + } + if (!success) { Isolate* isolate = info->isolate(); if (!isolate->has_pending_exception()) isolate->StackOverflow(); - return false; } - return true; + return success; } @@ -730,7 +750,8 @@ MUST_USE_RESULT static MaybeHandle GetUnoptimizedCodeCommon( SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); MaybeDisableOptimization(shared, lit->dont_optimize_reason()); - if (FLAG_ignition && info->closure()->PassesFilter(FLAG_ignition_filter)) { + if (FLAG_ignition && !shared->HasBuiltinFunctionId() && + info->closure()->PassesFilter(FLAG_ignition_filter)) { // Compile bytecode for the interpreter. if (!GenerateBytecode(info)) return MaybeHandle(); } else { @@ -750,6 +771,10 @@ MUST_USE_RESULT static MaybeHandle GetUnoptimizedCodeCommon( // Update the code and feedback vector for the shared function info. shared->ReplaceCode(*info->code()); shared->set_feedback_vector(*info->feedback_vector()); + if (info->has_bytecode_array()) { + DCHECK(shared->function_data()->IsUndefined()); + shared->set_function_data(*info->bytecode_array()); + } return info->code(); } @@ -776,7 +801,8 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { Handle code = info->code(); if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. - // Context specialization folds-in the context, so no sharing can occur. + // Function context specialization folds-in the function context, + // so no sharing can occur. if (info->is_function_context_specializing()) return; // Frame specialization implies function context specialization. DCHECK(!info->is_frame_specializing()); @@ -786,19 +812,18 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { if (function->shared()->bound()) return; // Cache optimized context-specific code. - if (FLAG_cache_optimized_code) { - Handle shared(function->shared()); - Handle literals(function->literals()); - Handle native_context(function->context()->native_context()); - SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, - literals, info->osr_ast_id()); - } + Handle shared(function->shared()); + Handle literals(function->literals()); + Handle native_context(function->context()->native_context()); + SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, + literals, info->osr_ast_id()); - // Do not cache context-independent code compiled for OSR. + // Do not cache (native) context-independent code compiled for OSR. if (code->is_turbofanned() && info->is_osr()) return; - // Cache optimized context-independent code. - if (FLAG_turbo_cache_shared_code && code->is_turbofanned()) { + // Cache optimized (native) context-independent code. + if (FLAG_turbo_cache_shared_code && code->is_turbofanned() && + !info->is_native_context_specializing()) { DCHECK(!info->is_function_context_specializing()); DCHECK(info->osr_ast_id().IsNone()); Handle shared(function->shared()); @@ -841,9 +866,12 @@ bool Compiler::ParseAndAnalyze(ParseInfo* info) { static bool GetOptimizedCodeNow(CompilationInfo* info) { + Isolate* isolate = info->isolate(); + CanonicalHandleScope canonical(isolate); + if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; - TimerEventScope timer(info->isolate()); + TimerEventScope timer(isolate); OptimizedCompileJob job(info); if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED || @@ -858,7 +886,7 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) { } // Success! - DCHECK(!info->isolate()->has_pending_exception()); + DCHECK(!isolate->has_pending_exception()); InsertCodeIntoOptimizedCodeMap(info); RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, info->shared_info()); @@ -868,6 +896,8 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) { static bool GetOptimizedCodeLater(CompilationInfo* info) { Isolate* isolate = info->isolate(); + CanonicalHandleScope canonical(isolate); + if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { if (FLAG_trace_concurrent_recompilation) { PrintF(" ** Compilation queue full, will retry optimizing "); @@ -1146,6 +1176,13 @@ void Compiler::CompileForLiveEdit(Handle