From 587e83c6d6fa9bba14f5b629fa2ee905dc6881e8 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 8 Apr 2013 20:25:29 +0200 Subject: [PATCH] v8: upgrade to 3.17.16 --- deps/v8/.gitignore | 5 + deps/v8/ChangeLog | 40 + deps/v8/OWNERS | 2 + deps/v8/build/common.gypi | 9 + deps/v8/include/v8-profiler.h | 119 ++- deps/v8/include/v8.h | 16 +- deps/v8/src/api.cc | 181 +++- deps/v8/src/api.h | 7 +- deps/v8/src/apiutils.h | 4 - deps/v8/src/arm/builtins-arm.cc | 21 +- deps/v8/src/arm/code-stubs-arm.cc | 110 +- deps/v8/src/arm/codegen-arm.cc | 6 +- deps/v8/src/arm/full-codegen-arm.cc | 30 +- deps/v8/src/arm/lithium-arm.cc | 43 +- deps/v8/src/arm/lithium-arm.h | 16 +- deps/v8/src/arm/lithium-codegen-arm.cc | 82 +- deps/v8/src/arm/lithium-codegen-arm.h | 4 + deps/v8/src/arm/macro-assembler-arm.cc | 82 +- deps/v8/src/arm/macro-assembler-arm.h | 16 +- deps/v8/src/arm/simulator-arm.cc | 26 +- deps/v8/src/arm/simulator-arm.h | 6 +- deps/v8/src/arm/stub-cache-arm.cc | 45 +- deps/v8/src/array.js | 210 ++-- deps/v8/src/assembler.cc | 11 - deps/v8/src/ast.cc | 12 +- deps/v8/src/ast.h | 83 +- deps/v8/src/bootstrapper.cc | 36 +- deps/v8/src/code-stubs-hydrogen.cc | 138 ++- deps/v8/src/code-stubs.cc | 11 +- deps/v8/src/code-stubs.h | 69 +- deps/v8/src/compiler.cc | 1 + deps/v8/src/contexts.h | 4 +- deps/v8/src/d8.cc | 8 +- deps/v8/src/d8.h | 5 - deps/v8/src/d8.js | 3 +- deps/v8/src/debug.cc | 9 +- deps/v8/src/debug.h | 1 + deps/v8/src/deoptimizer.cc | 106 +- deps/v8/src/deoptimizer.h | 12 +- deps/v8/src/elements-kind.h | 9 +- deps/v8/src/flag-definitions.h | 9 +- deps/v8/src/frames.cc | 23 +- deps/v8/src/full-codegen.cc | 28 + deps/v8/src/gdb-jit.cc | 39 +- deps/v8/src/gdb-jit.h | 4 +- deps/v8/src/global-handles.cc | 7 +- deps/v8/src/handles-inl.h | 2 +- deps/v8/src/handles.cc | 29 +- deps/v8/src/handles.h | 10 +- deps/v8/src/heap-inl.h | 4 +- deps/v8/src/heap-profiler.cc | 125 +-- deps/v8/src/heap-profiler.h | 46 +- deps/v8/src/heap-snapshot-generator-inl.h | 1 + deps/v8/src/heap-snapshot-generator.cc | 12 +- deps/v8/src/heap-snapshot-generator.h | 11 +- deps/v8/src/heap.cc | 28 +- deps/v8/src/heap.h | 9 +- deps/v8/src/hydrogen-instructions.cc | 35 +- deps/v8/src/hydrogen-instructions.h | 77 +- deps/v8/src/hydrogen.cc | 601 ++++++++--- deps/v8/src/hydrogen.h | 80 +- deps/v8/src/ia32/builtins-ia32.cc | 43 +- deps/v8/src/ia32/code-stubs-ia32.cc | 108 +- deps/v8/src/ia32/codegen-ia32.cc | 9 +- deps/v8/src/ia32/full-codegen-ia32.cc | 31 +- deps/v8/src/ia32/lithium-codegen-ia32.cc | 28 +- deps/v8/src/ia32/lithium-ia32.cc | 41 +- deps/v8/src/ia32/lithium-ia32.h | 14 - deps/v8/src/ia32/macro-assembler-ia32.cc | 88 +- deps/v8/src/ia32/macro-assembler-ia32.h | 32 +- deps/v8/src/ia32/stub-cache-ia32.cc | 44 +- deps/v8/src/ic-inl.h | 7 +- deps/v8/src/ic.cc | 271 +++-- deps/v8/src/ic.h | 7 +- deps/v8/src/interpreter-irregexp.cc | 10 +- deps/v8/src/isolate.cc | 25 +- deps/v8/src/isolate.h | 3 +- deps/v8/src/json-parser.h | 55 +- deps/v8/src/json-stringifier.h | 92 +- deps/v8/src/log.cc | 91 +- deps/v8/src/log.h | 1 + deps/v8/src/macros.py | 5 +- deps/v8/src/messages.js | 104 +- deps/v8/src/mips/OWNERS | 1 + deps/v8/src/mips/assembler-mips.cc | 10 +- deps/v8/src/mips/assembler-mips.h | 1 + deps/v8/src/mips/builtins-mips.cc | 21 +- deps/v8/src/mips/code-stubs-mips.cc | 141 +-- deps/v8/src/mips/codegen-mips.cc | 7 +- deps/v8/src/mips/full-codegen-mips.cc | 30 +- deps/v8/src/mips/lithium-codegen-mips.cc | 90 +- deps/v8/src/mips/lithium-codegen-mips.h | 4 + deps/v8/src/mips/lithium-mips.cc | 43 +- deps/v8/src/mips/lithium-mips.h | 17 +- deps/v8/src/mips/macro-assembler-mips.cc | 322 +++--- deps/v8/src/mips/macro-assembler-mips.h | 13 +- .../src/mips/regexp-macro-assembler-mips.cc | 1 + deps/v8/src/mips/simulator-mips.cc | 28 +- deps/v8/src/mips/simulator-mips.h | 6 +- deps/v8/src/mips/stub-cache-mips.cc | 45 +- deps/v8/src/mirror-debugger.js | 2 +- deps/v8/src/object-observe.js | 3 + deps/v8/src/objects-debug.cc | 12 + deps/v8/src/objects-inl.h | 55 +- deps/v8/src/objects-printer.cc | 15 + deps/v8/src/objects-visiting-inl.h | 19 +- deps/v8/src/objects-visiting.cc | 5 +- deps/v8/src/objects-visiting.h | 1 + deps/v8/src/objects.cc | 303 ++++-- deps/v8/src/objects.h | 69 +- deps/v8/src/parser.cc | 95 +- deps/v8/src/parser.h | 10 + deps/v8/src/platform-linux.cc | 4 +- deps/v8/src/platform-posix.cc | 17 +- deps/v8/src/platform.h | 2 +- deps/v8/src/preparser.cc | 60 +- deps/v8/src/preparser.h | 38 +- deps/v8/src/prettyprinter.cc | 11 + deps/v8/src/property.h | 8 +- deps/v8/src/runtime.cc | 993 ++++++------------ deps/v8/src/runtime.h | 14 +- deps/v8/src/runtime.js | 12 + deps/v8/src/scanner.cc | 2 +- deps/v8/src/scanner.h | 3 +- deps/v8/src/spaces-inl.h | 17 - deps/v8/src/spaces.cc | 8 +- deps/v8/src/spaces.h | 5 - deps/v8/src/stub-cache.cc | 82 +- deps/v8/src/stub-cache.h | 12 +- deps/v8/src/symbol.js | 56 +- deps/v8/src/token.h | 1 + deps/v8/src/type-info.cc | 17 +- deps/v8/src/typedarray.js | 98 ++ deps/v8/src/v8globals.h | 2 +- deps/v8/src/v8natives.js | 29 +- deps/v8/src/v8utils.h | 33 +- deps/v8/src/version.cc | 2 +- deps/v8/src/x64/builtins-x64.cc | 48 +- deps/v8/src/x64/code-stubs-x64.cc | 67 +- deps/v8/src/x64/codegen-x64.cc | 6 +- deps/v8/src/x64/full-codegen-x64.cc | 30 +- deps/v8/src/x64/lithium-codegen-x64.cc | 22 +- deps/v8/src/x64/lithium-x64.cc | 35 +- deps/v8/src/x64/lithium-x64.h | 16 +- deps/v8/src/x64/macro-assembler-x64.cc | 74 +- deps/v8/src/x64/macro-assembler-x64.h | 28 +- deps/v8/src/x64/stub-cache-x64.cc | 43 +- deps/v8/test/cctest/test-api.cc | 22 +- deps/v8/test/cctest/test-cpu-profiler.cc | 104 +- deps/v8/test/cctest/test-heap-profiler.cc | 230 ++-- deps/v8/test/cctest/test-heap.cc | 4 + deps/v8/test/cctest/test-profile-generator.cc | 10 +- deps/v8/test/cctest/test-strings.cc | 4 +- deps/v8/test/message/overwritten-builtins.out | 1 + deps/v8/test/mjsunit/array-non-smi-length.js | 46 + deps/v8/test/mjsunit/array-shift.js | 14 + deps/v8/test/mjsunit/array-splice.js | 10 +- deps/v8/test/mjsunit/array-unshift.js | 17 +- deps/v8/test/mjsunit/compiler/rotate.js | 1 + deps/v8/test/mjsunit/debug-evaluate-locals.js | 16 +- .../mjsunit/debug-liveedit-compile-error.js | 2 + deps/v8/test/mjsunit/elements-kind.js | 7 +- deps/v8/test/mjsunit/error-accessors.js | 1 + .../mjsunit/harmony/generators-parsing.js | 100 ++ .../v8/test/mjsunit/harmony/object-observe.js | 25 +- .../test/mjsunit/harmony/proxies-symbols.js | 106 ++ deps/v8/test/mjsunit/harmony/symbols.js | 164 ++- deps/v8/test/mjsunit/harmony/typedarrays.js | 136 +++ deps/v8/test/mjsunit/json.js | 117 ++- deps/v8/test/mjsunit/json2.js | 65 +- deps/v8/test/mjsunit/nans.js | 103 ++ .../external-and-normal-array-polymorphism.js | 48 + .../test/mjsunit/regress/negative_lookup.js | 65 ++ deps/v8/test/mjsunit/regress/readonly1.js | 71 ++ deps/v8/test/mjsunit/regress/readonly2.js | 62 ++ deps/v8/test/mjsunit/regress/readonly3.js | 65 ++ deps/v8/test/mjsunit/regress/readonly4.js | 74 ++ deps/v8/test/mjsunit/regress/regress-105.js | 44 + .../v8/test/mjsunit/regress/regress-166379.js | 1 + .../v8/test/mjsunit/regress/regress-201590.js | 66 ++ deps/v8/test/mjsunit/regress/regress-2374.js | 1 + deps/v8/test/mjsunit/regress/regress-2419.js | 1 + deps/v8/test/mjsunit/regress/regress-2438.js | 1 + deps/v8/test/mjsunit/regress/regress-2444.js | 2 + deps/v8/test/mjsunit/regress/regress-2451.js | 1 + deps/v8/test/mjsunit/regress/regress-2564.js | 122 +++ deps/v8/test/mjsunit/regress/regress-2570.js | 1 + deps/v8/test/mjsunit/regress/regress-2593.js | 61 ++ deps/v8/test/mjsunit/regress/regress-2596.js | 56 + deps/v8/test/mjsunit/regress/regress-753.js | 2 +- .../mjsunit/regress/regress-crbug-146910.js | 15 +- .../mjsunit/regress/regress-crbug-158185.js | 1 + .../mjsunit/regress/regress-crbug-171715.js | 87 ++ .../mjsunit/regress/regress-crbug-178790.js | 1 + .../mjsunit/regress/regress-crbug-217858.js | 40 + .../mjsunit/regress/regress-crbug-222893.js | 64 ++ .../regress/regress-json-stringify-gc.js | 1 + .../test/mjsunit/regress/regress-latin-1.js | 1 + deps/v8/test/mjsunit/regress/setter.js | 66 ++ deps/v8/test/mjsunit/shift-for-integer-div.js | 1 + deps/v8/test/mjsunit/string-natives.js | 1 + deps/v8/tools/grokdump.py | 287 ++--- deps/v8/tools/gyp/v8.gyp | 3 +- 203 files changed, 6256 insertions(+), 3512 deletions(-) create mode 100644 deps/v8/src/mips/OWNERS create mode 100644 deps/v8/src/typedarray.js create mode 100644 deps/v8/test/mjsunit/array-non-smi-length.js create mode 100644 deps/v8/test/mjsunit/harmony/generators-parsing.js create mode 100644 deps/v8/test/mjsunit/harmony/proxies-symbols.js create mode 100644 deps/v8/test/mjsunit/harmony/typedarrays.js create mode 100644 deps/v8/test/mjsunit/nans.js create mode 100644 deps/v8/test/mjsunit/regress/external-and-normal-array-polymorphism.js create mode 100644 deps/v8/test/mjsunit/regress/negative_lookup.js create mode 100644 deps/v8/test/mjsunit/regress/readonly1.js create mode 100644 deps/v8/test/mjsunit/regress/readonly2.js create mode 100644 deps/v8/test/mjsunit/regress/readonly3.js create mode 100644 deps/v8/test/mjsunit/regress/readonly4.js create mode 100644 deps/v8/test/mjsunit/regress/regress-105.js create mode 100644 deps/v8/test/mjsunit/regress/regress-201590.js create mode 100644 deps/v8/test/mjsunit/regress/regress-2564.js create mode 100644 deps/v8/test/mjsunit/regress/regress-2593.js create mode 100644 deps/v8/test/mjsunit/regress/regress-2596.js create mode 100644 deps/v8/test/mjsunit/regress/regress-crbug-171715.js create mode 100644 deps/v8/test/mjsunit/regress/regress-crbug-217858.js create mode 100644 deps/v8/test/mjsunit/regress/regress-crbug-222893.js create mode 100644 deps/v8/test/mjsunit/regress/setter.js diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index 0bf9313353..fe8425f021 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -18,6 +18,7 @@ #*# *~ .cpplint-cache +.d8_history d8 d8_g shell @@ -50,3 +51,7 @@ shell_g /xcodebuild TAGS *.Makefile +GTAGS +GRTAGS +GSYMS +GPATH diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 11c80d7175..5bd017fc03 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,43 @@ +2013-04-04: Version 3.17.16 + + Stack trace API: poison stack frames below the first strict mode frame. + (issue 2564) + + Made Isolate::GetHeapStatistics robust against half-initialized + isolates (Chromium issue 2591). + + Finished implementation of ES6 symbols aka. private names (issue 2158). + + Performance and stability improvements on all platforms. + + +2013-03-21: Version 3.17.15 + + Rolled back API changes to maintain compatibility with older + 3.17.x versions of V8. + + Disable zapping of global handles in release mode. + + Always mark the entire valid prefix of the descriptor array. + (Chromium issue 196331) + + Use internal memcpy for CopyWords and when copying code. + (Chromium issue 196330) + + Performance and stability improvements on all platforms. + + +2013-03-20: Version 3.17.14 + + Use internal memcpy when initializing code objects. + (Chromium issue 196330) + + Disabled weak embedded maps because of crashes. + (Chromium issues 172489, 217858) + + Performance and stability improvements on all platforms. + + 2013-03-19: Version 3.17.13 Turned Flags into a uint32_t typedef (Chromium issue 194749). diff --git a/deps/v8/OWNERS b/deps/v8/OWNERS index 941e5fe07d..0333d15184 100644 --- a/deps/v8/OWNERS +++ b/deps/v8/OWNERS @@ -1,4 +1,6 @@ danno@chromium.org +dslomov@chromium.org +hpayer@chromium.org jkummerow@chromium.org mmassi@chromium.org mstarzinger@chromium.org diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index 38ed4f4c95..a3c9ed0943 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -409,6 +409,15 @@ }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" \ or OS=="android"', { + 'cflags!': [ + '-O2', + '-Os', + ], + 'cflags': [ + '-fdata-sections', + '-ffunction-sections', + '-O3', + ], 'conditions': [ [ 'gcc_version==44 and clang==0', { 'cflags': [ diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 41fe8a1999..68f377c606 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -135,7 +135,7 @@ class V8EXPORT CpuProfile { /** * Returns number of samples recorded. The samples are not recorded unless - * |record_samples| parameter of CpuProfiler::StartProfiling is true. + * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true. */ int GetSamplesCount() const; @@ -158,7 +158,8 @@ class V8EXPORT CpuProfile { /** - * Interface for controlling CPU profiling. + * Interface for controlling CPU profiling. Instance of the + * profiler can be retrieved using v8::Isolate::GetCpuProfiler. */ class V8EXPORT CpuProfiler { public: @@ -171,22 +172,34 @@ class V8EXPORT CpuProfiler { * obtaining profiling results. */ + /** Deprecated. Use GetProfileCount instead. */ + static int GetProfilesCount(); /** * Returns the number of profiles collected (doesn't include * profiles that are being collected at the moment of call.) */ - static int GetProfilesCount(); + int GetProfileCount(); - /** Returns a profile by index. */ + /** Deprecated. Use GetCpuProfile instead. */ static const CpuProfile* GetProfile( int index, Handle security_token = Handle()); + /** Returns a profile by index. */ + const CpuProfile* GetCpuProfile( + int index, + Handle security_token = Handle()); - /** Returns a profile by uid. */ + /** Deprecated. Use FindProfile instead. */ static const CpuProfile* FindProfile( unsigned uid, Handle security_token = Handle()); + /** Returns a profile by uid. */ + const CpuProfile* FindCpuProfile( + unsigned uid, + Handle security_token = Handle()); + /** Deprecated. Use StartCpuProfiling instead. */ + static void StartProfiling(Handle title, bool record_samples = false); /** * Starts collecting CPU profile. Title may be an empty string. It * is allowed to have several profiles being collected at @@ -198,22 +211,34 @@ class V8EXPORT CpuProfiler { * |record_samples| parameter controls whether individual samples should * be recorded in addition to the aggregated tree. */ - static void StartProfiling(Handle title, bool record_samples = false); + void StartCpuProfiling(Handle title, bool record_samples = false); + /** Deprecated. Use StopCpuProfiling instead. */ + static const CpuProfile* StopProfiling( + Handle title, + Handle security_token = Handle()); /** * Stops collecting CPU profile with a given title and returns it. * If the title given is empty, finishes the last profile started. */ - static const CpuProfile* StopProfiling( + const CpuProfile* StopCpuProfiling( Handle title, Handle security_token = Handle()); + /** Deprecated. Use DeleteAllCpuProfiles instead. */ + static void DeleteAllProfiles(); /** * Deletes all existing profiles, also cancelling all profiling * activity. All previously returned pointers to profiles and their * contents become invalid after this call. */ - static void DeleteAllProfiles(); + void DeleteAllCpuProfiles(); + + private: + CpuProfiler(); + ~CpuProfiler(); + CpuProfiler(const CpuProfiler&); + CpuProfiler& operator=(const CpuProfiler&); }; @@ -321,8 +346,8 @@ class V8EXPORT HeapSnapshot { kJSON = 0 // See format description near 'Serialize' method. }; - /** Returns heap snapshot type. */ - Type GetType() const; + /** Deprecated. Returns kFull. */ + V8_DEPRECATED(Type GetType() const); /** Returns heap snapshot UID (assigned by the profiler.) */ unsigned GetUid() const; @@ -385,7 +410,8 @@ class V8EXPORT HeapSnapshot { class RetainedObjectInfo; /** - * Interface for controlling heap profiling. + * Interface for controlling heap profiling. Instance of the + * profiler can be retrieved using v8::Isolate::GetHeapProfiler. */ class V8EXPORT HeapProfiler { public: @@ -398,20 +424,28 @@ class V8EXPORT HeapProfiler { typedef RetainedObjectInfo* (*WrapperInfoCallback) (uint16_t class_id, Handle wrapper); - /** Returns the number of snapshots taken. */ + /** Deprecated. Use GetSnapshotCount instead. */ static int GetSnapshotsCount(); + /** Returns the number of snapshots taken. */ + int GetSnapshotCount(); - /** Returns a snapshot by index. */ + /** Deprecated. Use GetHeapSnapshot instead. */ static const HeapSnapshot* GetSnapshot(int index); + /** Returns a snapshot by index. */ + const HeapSnapshot* GetHeapSnapshot(int index); - /** Returns a profile by uid. */ + /** Deprecated. Use FindHeapSnapshot instead. */ static const HeapSnapshot* FindSnapshot(unsigned uid); + /** Returns a profile by uid. */ + const HeapSnapshot* FindHeapSnapshot(unsigned uid); + /** Deprecated. Use GetObjectId instead. */ + static SnapshotObjectId GetSnapshotObjectId(Handle value); /** * Returns SnapshotObjectId for a heap object referenced by |value| if * it has been seen by the heap profiler, kUnknownObjectId otherwise. */ - static SnapshotObjectId GetSnapshotObjectId(Handle value); + SnapshotObjectId GetObjectId(Handle value); /** * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return @@ -424,33 +458,42 @@ class V8EXPORT HeapProfiler { * Callback interface for retrieving user friendly names of global objects. */ class ObjectNameResolver { - public: + public: /** * Returns name to be used in the heap snapshot for given node. Returned * string must stay alive until snapshot collection is completed. */ virtual const char* GetName(Handle object) = 0; - protected: + protected: virtual ~ObjectNameResolver() {} }; + /** Deprecated. Use TakeHeapSnapshot instead. */ + static const HeapSnapshot* TakeSnapshot( + Handle title, + HeapSnapshot::Type type = HeapSnapshot::kFull, + ActivityControl* control = NULL, + ObjectNameResolver* global_object_name_resolver = NULL); /** * Takes a heap snapshot and returns it. Title may be an empty string. - * See HeapSnapshot::Type for types description. */ - static const HeapSnapshot* TakeSnapshot( + const HeapSnapshot* TakeHeapSnapshot( Handle title, - HeapSnapshot::Type type = HeapSnapshot::kFull, ActivityControl* control = NULL, ObjectNameResolver* global_object_name_resolver = NULL); + + /** Deprecated. Use StartTrackingHeapObjects instead. */ + static void StartHeapObjectsTracking(); /** * Starts tracking of heap objects population statistics. After calling * this method, all heap objects relocations done by the garbage collector * are being registered. */ - static void StartHeapObjectsTracking(); + void StartTrackingHeapObjects(); + /** Deprecated. Use GetHeapStats instead. */ + static SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); /** * Adds a new time interval entry to the aggregated statistics array. The * time interval entry contains information on the current heap objects @@ -460,28 +503,36 @@ class V8EXPORT HeapProfiler { * HeapStatsUpdate structure instances. * The return value of the function is the last seen heap object Id. * - * StartHeapObjectsTracking must be called before the first call to this + * StartTrackingHeapObjects must be called before the first call to this * method. */ - static SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); + SnapshotObjectId GetHeapStats(OutputStream* stream); + /** Deprecated. Use StopTrackingHeapObjects instead. */ + static void StopHeapObjectsTracking(); /** * Stops tracking of heap objects population statistics, cleans up all * collected data. StartHeapObjectsTracking must be called again prior to * calling PushHeapObjectsStats next time. */ - static void StopHeapObjectsTracking(); + void StopTrackingHeapObjects(); + /** Deprecated. Use DeleteAllHeapSnapshots instead. */ + static void DeleteAllSnapshots(); /** * Deletes all snapshots taken. All previously returned pointers to * snapshots and their contents become invalid after this call. */ - static void DeleteAllSnapshots(); + void DeleteAllHeapSnapshots(); - /** Binds a callback to embedder's class ID. */ + /** Deprecated. Use SetWrapperClassInfoProvider instead. */ static void DefineWrapperClass( uint16_t class_id, WrapperInfoCallback callback); + /** Binds a callback to embedder's class ID. */ + void SetWrapperClassInfoProvider( + uint16_t class_id, + WrapperInfoCallback callback); /** * Default value of persistent handle class ID. Must not be used to @@ -490,11 +541,21 @@ class V8EXPORT HeapProfiler { */ static const uint16_t kPersistentHandleNoClassId = 0; - /** Returns the number of currently existing persistent handles. */ + /** + * Deprecated. Returns the number of currently existing persistent handles. + */ static int GetPersistentHandleCount(); - /** Returns memory used for profiler internal data and snapshots. */ + /** Deprecated. Use GetHeapProfilerMemorySize instead. */ static size_t GetMemorySizeUsedByProfiler(); + /** Returns memory used for profiler internal data and snapshots. */ + size_t GetProfilerMemorySize(); + + private: + HeapProfiler(); + ~HeapProfiler(); + HeapProfiler(const HeapProfiler&); + HeapProfiler& operator=(const HeapProfiler&); }; @@ -574,7 +635,7 @@ class V8EXPORT RetainedObjectInfo { // NOLINT /** * A struct for exporting HeapStats data from V8, using "push" model. - * See HeapProfiler::PushHeapObjectsStats. + * See HeapProfiler::GetHeapStats. */ struct HeapStatsUpdate { HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size) diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 329576fa94..9adb1c041c 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -103,12 +103,14 @@ class Array; class Boolean; class BooleanObject; class Context; +class CpuProfiler; class Data; class Date; class DeclaredAccessorDescriptor; class External; class Function; class FunctionTemplate; +class HeapProfiler; class ImplementationUtilities; class Int32; class Integer; @@ -3022,6 +3024,18 @@ class V8EXPORT Isolate { */ intptr_t AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes); + /** + * Returns heap profiler for this isolate. Will return NULL until the isolate + * is initialized. + */ + HeapProfiler* GetHeapProfiler(); + + /** + * Returns CPU profiler for this isolate. Will return NULL until the isolate + * is initialized. + */ + CpuProfiler* GetCpuProfiler(); + private: Isolate(); Isolate(const Isolate&); @@ -4274,7 +4288,7 @@ class Internals { static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; static const int kContextHeaderSize = 2 * kApiPointerSize; - static const int kContextEmbedderDataIndex = 54; + static const int kContextEmbedderDataIndex = 55; static const int kFullStringRepresentationMask = 0x07; static const int kStringEncodingMask = 0x4; static const int kExternalTwoByteRepresentationTag = 0x02; diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index dfa57654db..65663ba5c6 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -477,14 +477,6 @@ void V8::SetAllowCodeGenerationFromStringsCallback( } -#ifdef DEBUG -void ImplementationUtilities::ZapHandleRange(i::Object** begin, - i::Object** end) { - i::HandleScope::ZapRange(begin, end); -} -#endif - - void V8::SetFlagsFromString(const char* str, int length) { i::FlagList::SetFlagsFromString(str, length); } @@ -706,7 +698,7 @@ void HandleScope::Leave() { i::HandleScope::DeleteExtensions(isolate_); } -#ifdef DEBUG +#ifdef ENABLE_EXTRA_CHECKS i::HandleScope::ZapRange(prev_next_, prev_limit_); #endif } @@ -3197,7 +3189,7 @@ Local v8::Object::ObjectProtoToString() { i::Handle name(self->class_name(), isolate); // Native implementation of Object.prototype.toString (v8natives.js): - // var c = %ClassOf(this); + // var c = %_ClassOf(this); // if (c === 'Arguments') c = 'Object'; // return "[object " + c + "]"; @@ -5807,6 +5799,20 @@ intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) { } +HeapProfiler* Isolate::GetHeapProfiler() { + i::HeapProfiler* heap_profiler = + reinterpret_cast(this)->heap_profiler(); + return reinterpret_cast(heap_profiler); +} + + +CpuProfiler* Isolate::GetCpuProfiler() { + i::CpuProfiler* cpu_profiler = + reinterpret_cast(this)->cpu_profiler(); + return reinterpret_cast(cpu_profiler); +} + + void V8::SetGlobalGCPrologueCallback(GCCallback callback) { i::Isolate* isolate = i::Isolate::Current(); if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return; @@ -5979,6 +5985,14 @@ void Isolate::Exit() { void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) { i::Isolate* isolate = reinterpret_cast(this); + if (!isolate->IsInitialized()) { + heap_statistics->total_heap_size_ = 0; + heap_statistics->total_heap_size_executable_ = 0; + heap_statistics->total_physical_size_ = 0; + heap_statistics->used_heap_size_ = 0; + heap_statistics->heap_size_limit_ = 0; + return; + } i::Heap* heap = isolate->heap(); heap_statistics->total_heap_size_ = heap->CommittedMemory(); heap_statistics->total_heap_size_executable_ = @@ -6532,6 +6546,11 @@ int CpuProfiler::GetProfilesCount() { } +int CpuProfiler::GetProfileCount() { + return reinterpret_cast(this)->GetProfilesCount(); +} + + const CpuProfile* CpuProfiler::GetProfile(int index, Handle security_token) { i::Isolate* isolate = i::Isolate::Current(); @@ -6545,6 +6564,15 @@ const CpuProfile* CpuProfiler::GetProfile(int index, } +const CpuProfile* CpuProfiler::GetCpuProfile(int index, + Handle security_token) { + return reinterpret_cast( + reinterpret_cast(this)->GetProfile( + security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token), + index)); +} + + const CpuProfile* CpuProfiler::FindProfile(unsigned uid, Handle security_token) { i::Isolate* isolate = i::Isolate::Current(); @@ -6558,6 +6586,15 @@ const CpuProfile* CpuProfiler::FindProfile(unsigned uid, } +const CpuProfile* CpuProfiler::FindCpuProfile(unsigned uid, + Handle security_token) { + return reinterpret_cast( + reinterpret_cast(this)->FindProfile( + security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token), + uid)); +} + + void CpuProfiler::StartProfiling(Handle title, bool record_samples) { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling"); @@ -6567,6 +6604,12 @@ void CpuProfiler::StartProfiling(Handle title, bool record_samples) { } +void CpuProfiler::StartCpuProfiling(Handle title, bool record_samples) { + reinterpret_cast(this)->StartProfiling( + *Utils::OpenHandle(*title), record_samples); +} + + const CpuProfile* CpuProfiler::StopProfiling(Handle title, Handle security_token) { i::Isolate* isolate = i::Isolate::Current(); @@ -6580,6 +6623,15 @@ const CpuProfile* CpuProfiler::StopProfiling(Handle title, } +const CpuProfile* CpuProfiler::StopCpuProfiling(Handle title, + Handle security_token) { + return reinterpret_cast( + reinterpret_cast(this)->StopProfiling( + security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token), + *Utils::OpenHandle(*title))); +} + + void CpuProfiler::DeleteAllProfiles() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles"); @@ -6589,6 +6641,11 @@ void CpuProfiler::DeleteAllProfiles() { } +void CpuProfiler::DeleteAllCpuProfiles() { + reinterpret_cast(this)->DeleteAllProfiles(); +} + + static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) { return const_cast( reinterpret_cast(edge)); @@ -6708,11 +6765,11 @@ static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) { void HeapSnapshot::Delete() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapSnapshot::Delete"); - if (i::HeapProfiler::GetSnapshotsCount() > 1) { + if (isolate->heap_profiler()->GetSnapshotsCount() > 1) { ToInternal(this)->Delete(); } else { // If this is the last snapshot, clean up all accessory data as well. - i::HeapProfiler::DeleteAllSnapshots(); + isolate->heap_profiler()->DeleteAllSnapshots(); } } @@ -6720,7 +6777,7 @@ void HeapSnapshot::Delete() { HeapSnapshot::Type HeapSnapshot::GetType() const { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapSnapshot::GetType"); - return static_cast(ToInternal(this)->type()); + return kFull; } @@ -6797,7 +6854,12 @@ void HeapSnapshot::Serialize(OutputStream* stream, int HeapProfiler::GetSnapshotsCount() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount"); - return i::HeapProfiler::GetSnapshotsCount(); + return isolate->heap_profiler()->GetSnapshotsCount(); +} + + +int HeapProfiler::GetSnapshotCount() { + return reinterpret_cast(this)->GetSnapshotsCount(); } @@ -6805,7 +6867,13 @@ const HeapSnapshot* HeapProfiler::GetSnapshot(int index) { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot"); return reinterpret_cast( - i::HeapProfiler::GetSnapshot(index)); + isolate->heap_profiler()->GetSnapshot(index)); +} + + +const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) { + return reinterpret_cast( + reinterpret_cast(this)->GetSnapshot(index)); } @@ -6813,7 +6881,13 @@ const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot"); return reinterpret_cast( - i::HeapProfiler::FindSnapshot(uid)); + isolate->heap_profiler()->FindSnapshot(uid)); +} + + +const HeapSnapshot* HeapProfiler::FindHeapSnapshot(unsigned uid) { + return reinterpret_cast( + reinterpret_cast(this)->FindSnapshot(uid)); } @@ -6821,7 +6895,13 @@ SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle value) { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotObjectId"); i::Handle obj = Utils::OpenHandle(*value); - return i::HeapProfiler::GetSnapshotObjectId(obj); + return isolate->heap_profiler()->GetSnapshotObjectId(obj); +} + + +SnapshotObjectId HeapProfiler::GetObjectId(Handle value) { + i::Handle obj = Utils::OpenHandle(*value); + return reinterpret_cast(this)->GetSnapshotObjectId(obj); } @@ -6831,45 +6911,67 @@ const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle title, ObjectNameResolver* resolver) { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot"); - i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull; - switch (type) { - case HeapSnapshot::kFull: - internal_type = i::HeapSnapshot::kFull; - break; - default: - UNREACHABLE(); - } return reinterpret_cast( - i::HeapProfiler::TakeSnapshot( - *Utils::OpenHandle(*title), internal_type, control, resolver)); + isolate->heap_profiler()->TakeSnapshot( + *Utils::OpenHandle(*title), control, resolver)); +} + + +const HeapSnapshot* HeapProfiler::TakeHeapSnapshot( + Handle title, + ActivityControl* control, + ObjectNameResolver* resolver) { + return reinterpret_cast( + reinterpret_cast(this)->TakeSnapshot( + *Utils::OpenHandle(*title), control, resolver)); } void HeapProfiler::StartHeapObjectsTracking() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::StartHeapObjectsTracking"); - i::HeapProfiler::StartHeapObjectsTracking(); + isolate->heap_profiler()->StartHeapObjectsTracking(); +} + + +void HeapProfiler::StartTrackingHeapObjects() { + reinterpret_cast(this)->StartHeapObjectsTracking(); } void HeapProfiler::StopHeapObjectsTracking() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::StopHeapObjectsTracking"); - i::HeapProfiler::StopHeapObjectsTracking(); + isolate->heap_profiler()->StopHeapObjectsTracking(); +} + + +void HeapProfiler::StopTrackingHeapObjects() { + reinterpret_cast(this)->StopHeapObjectsTracking(); } SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::PushHeapObjectsStats"); - return i::HeapProfiler::PushHeapObjectsStats(stream); + return isolate->heap_profiler()->PushHeapObjectsStats(stream); +} + + +SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) { + return reinterpret_cast(this)->PushHeapObjectsStats(stream); } void HeapProfiler::DeleteAllSnapshots() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots"); - i::HeapProfiler::DeleteAllSnapshots(); + isolate->heap_profiler()->DeleteAllSnapshots(); +} + + +void HeapProfiler::DeleteAllHeapSnapshots() { + reinterpret_cast(this)->DeleteAllSnapshots(); } @@ -6880,6 +6982,13 @@ void HeapProfiler::DefineWrapperClass(uint16_t class_id, } +void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id, + WrapperInfoCallback callback) { + reinterpret_cast(this)->DefineWrapperClass(class_id, + callback); +} + + int HeapProfiler::GetPersistentHandleCount() { i::Isolate* isolate = i::Isolate::Current(); return isolate->global_handles()->NumberOfGlobalHandles(); @@ -6887,7 +6996,13 @@ int HeapProfiler::GetPersistentHandleCount() { size_t HeapProfiler::GetMemorySizeUsedByProfiler() { - return i::HeapProfiler::GetMemorySizeUsedByProfiler(); + return i::Isolate::Current()->heap_profiler()->GetMemorySizeUsedByProfiler(); +} + + +size_t HeapProfiler::GetProfilerMemorySize() { + return reinterpret_cast(this)-> + GetMemorySizeUsedByProfiler(); } @@ -7082,7 +7197,7 @@ DeferredHandles::~DeferredHandles() { isolate_->UnlinkDeferredHandles(this); for (int i = 0; i < blocks_.length(); i++) { -#ifdef DEBUG +#ifdef ENABLE_EXTRA_CHECKS HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]); #endif isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]); diff --git a/deps/v8/src/api.h b/deps/v8/src/api.h index ac6b8342c5..d73646d99d 100644 --- a/deps/v8/src/api.h +++ b/deps/v8/src/api.h @@ -294,6 +294,9 @@ MAKE_TO_LOCAL(ToLocal, DeclaredAccessorDescriptor, DeclaredAccessorDescriptor) v8::internal::Handle Utils::OpenHandle( \ const v8::From* that, bool allow_empty_handle) { \ EXTRA_CHECK(allow_empty_handle || that != NULL); \ + EXTRA_CHECK(that == NULL || \ + !(*reinterpret_cast( \ + const_cast(that)))->IsFailure()); \ return v8::internal::Handle( \ reinterpret_cast(const_cast(that))); \ } @@ -569,8 +572,8 @@ void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) { #endif blocks_.RemoveLast(); -#ifdef DEBUG - v8::ImplementationUtilities::ZapHandleRange(block_start, block_limit); +#ifdef ENABLE_EXTRA_CHECKS + internal::HandleScope::ZapRange(block_start, block_limit); #endif if (spare_ != NULL) { DeleteArray(spare_); diff --git a/deps/v8/src/apiutils.h b/deps/v8/src/apiutils.h index 71c0e1c2c4..9831f08669 100644 --- a/deps/v8/src/apiutils.h +++ b/deps/v8/src/apiutils.h @@ -67,10 +67,6 @@ class ImplementationUtilities { // Introduce an alias for the handle scope data to allow non-friends // to access the HandleScope data. typedef v8::HandleScope::Data HandleScopeData; - -#ifdef DEBUG - static void ZapHandleRange(internal::Object** begin, internal::Object** end); -#endif }; } // namespace v8 diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index 2946b355af..ebb9e1235f 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -221,13 +221,12 @@ static void AllocateJSArray(MacroAssembler* masm, __ add(elements_array_end, elements_array_end, Operand(array_size, ASR, kSmiTagSize)); - __ AllocateInNewSpace( - elements_array_end, - result, - scratch1, - scratch2, - gc_required, - static_cast(TAG_OBJECT | SIZE_IN_WORDS)); + __ Allocate(elements_array_end, + result, + scratch1, + scratch2, + gc_required, + static_cast(TAG_OBJECT | SIZE_IN_WORDS)); // Allocated the JSArray. Now initialize the fields except for the elements // array. @@ -874,7 +873,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // r1: constructor function // r2: initial map __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset)); - __ AllocateInNewSpace(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS); + __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS); // Allocated the JSObject, now initialize the fields. Map is set to // initial map and properties and elements are set to empty fixed array. @@ -949,7 +948,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // r4: JSObject // r5: start of next object __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize)); - __ AllocateInNewSpace( + __ Allocate( r0, r5, r6, @@ -1105,10 +1104,6 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE); __ b(ge, &exit); - // Symbols are "objects". - __ CompareInstanceType(r1, r3, SYMBOL_TYPE); - __ b(eq, &exit); - // Throw away the result of the constructor invocation and use the // on-stack receiver as the result. __ bind(&use_receiver); diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index b1ffaea14d..d982f27065 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -61,6 +61,17 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( } +void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor) { + static Register registers[] = { r2, r1, r0 }; + descriptor->register_param_count_ = 3; + descriptor->register_params_ = registers; + descriptor->deoptimization_handler_ = + FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); +} + + void TransitionElementsKindStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { @@ -84,7 +95,7 @@ static void InitializeArrayConstructorDescriptor(Isolate* isolate, // stack param count needs (constructor pointer, and single argument) descriptor->stack_parameter_count_ = &r0; descriptor->register_params_ = registers; - descriptor->extra_expression_stack_count_ = 1; + descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = FUNCTION_ADDR(ArrayConstructor_StubFailure); } @@ -2623,8 +2634,8 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, OverwriteMode mode) { Register left = r1; Register right = r0; - Register scratch1 = r7; - Register scratch2 = r9; + Register scratch1 = r6; + Register scratch2 = r7; Register scratch3 = r4; ASSERT(smi_operands || (not_numbers != NULL)); @@ -2639,7 +2650,7 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, __ JumpIfNotSmi(right, miss); } - Register heap_number_map = r6; + Register heap_number_map = r9; __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); switch (op) { @@ -4477,35 +4488,6 @@ void InstanceofStub::Generate(MacroAssembler* masm) { } -void ArrayLengthStub::Generate(MacroAssembler* masm) { - Label miss; - Register receiver; - if (kind() == Code::KEYED_LOAD_IC) { - // ----------- S t a t e ------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- - __ cmp(r0, Operand(masm->isolate()->factory()->length_string())); - __ b(ne, &miss); - receiver = r1; - } else { - ASSERT(kind() == Code::LOAD_IC); - // ----------- S t a t e ------------- - // -- r2 : name - // -- lr : return address - // -- r0 : receiver - // -- sp[0] : receiver - // ----------------------------------- - receiver = r0; - } - - StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss); - __ bind(&miss); - StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind())); -} - - void FunctionPrototypeStub::Generate(MacroAssembler* masm) { Label miss; Register receiver; @@ -4780,7 +4762,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) { __ add(r9, r9, Operand(Heap::kArgumentsObjectSize)); // Do the allocation of all three objects in one go. - __ AllocateInNewSpace(r9, r0, r3, r4, &runtime, TAG_OBJECT); + __ Allocate(r9, r0, r3, r4, &runtime, TAG_OBJECT); // r0 = address of new object(s) (tagged) // r2 = argument count (tagged) @@ -4956,13 +4938,8 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize)); // Do the allocation of both objects in one go. - __ AllocateInNewSpace(r1, - r0, - r2, - r3, - &runtime, - static_cast(TAG_OBJECT | - SIZE_IN_WORDS)); + __ Allocate(r1, r0, r2, r3, &runtime, + static_cast(TAG_OBJECT | SIZE_IN_WORDS)); // Get the arguments boilerplate from the current native context. __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); @@ -5466,7 +5443,7 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) { (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize; __ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize)); __ add(r2, r5, Operand(objects_size)); - __ AllocateInNewSpace( + __ Allocate( r2, // In: Size, in words. r0, // Out: Start of allocation (tagged). r3, // Scratch register. @@ -7408,33 +7385,31 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ cmp(entity_name, tmp); __ b(eq, done); - if (i != kInlinedProbes - 1) { - // Load the hole ready for use below: - __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); + // Load the hole ready for use below: + __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); - // Stop if found the property. - __ cmp(entity_name, Operand(Handle(name))); - __ b(eq, miss); + // Stop if found the property. + __ cmp(entity_name, Operand(Handle(name))); + __ b(eq, miss); - Label good; - __ cmp(entity_name, tmp); - __ b(eq, &good); + Label good; + __ cmp(entity_name, tmp); + __ b(eq, &good); - // Check if the entry name is not a unique name. - __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); - __ ldrb(entity_name, - FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); - __ tst(entity_name, Operand(kIsInternalizedMask)); - __ b(ne, &good); - __ cmp(entity_name, Operand(SYMBOL_TYPE)); - __ b(ne, miss); - - __ bind(&good); - - // Restore the properties. - __ ldr(properties, - FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - } + // Check if the entry name is not a unique name. + __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); + __ ldrb(entity_name, + FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); + __ tst(entity_name, Operand(kIsInternalizedMask)); + __ b(ne, &good); + __ cmp(entity_name, Operand(SYMBOL_TYPE)); + __ b(ne, miss); + + __ bind(&good); + + // Restore the properties. + __ ldr(properties, + FieldMemOperand(receiver, JSObject::kPropertiesOffset)); } const int spill_mask = @@ -7987,6 +7962,9 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { int parameter_count_offset = StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; __ ldr(r1, MemOperand(fp, parameter_count_offset)); + if (function_mode_ == JS_FUNCTION_STUB_MODE) { + __ add(r1, r1, Operand(1)); + } masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); __ mov(r1, Operand(r1, LSL, kPointerSizeLog2)); __ add(sp, sp, r1); diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index ff97ab5094..1c829469ce 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -207,7 +207,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( // Use lr as a temporary register. __ mov(lr, Operand(r5, LSL, 2)); __ add(lr, lr, Operand(FixedDoubleArray::kHeaderSize)); - __ AllocateInNewSpace(lr, r6, r7, r9, &gc_required, DOUBLE_ALIGNMENT); + __ Allocate(lr, r6, r7, r9, &gc_required, DOUBLE_ALIGNMENT); // r6: destination FixedDoubleArray, not tagged as heap object. // Set destination FixedDoubleArray's length and map. @@ -348,7 +348,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( // Allocate new FixedArray. __ mov(r0, Operand(FixedDoubleArray::kHeaderSize)); __ add(r0, r0, Operand(r5, LSL, 1)); - __ AllocateInNewSpace(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); + __ Allocate(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS); // r6: destination FixedArray, not tagged as heap object // Set destination FixedDoubleArray's length and map. __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex); @@ -691,7 +691,7 @@ void Code::PatchPlatformCodeAge(byte* sequence, uint32_t young_length; byte* young_sequence = GetNoCodeAgeSequence(&young_length); if (age == kNoAge) { - memcpy(sequence, young_sequence, young_length); + CopyBytes(sequence, young_sequence, young_length); CPU::FlushICache(sequence, young_length); } else { Code* stub = GetCodeAgeStub(age, parity); diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index 1df1649d3d..6086645db3 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -2764,28 +2764,6 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( } -void FullCodeGenerator::EmitIsSymbol(CallRuntime* expr) { - ZoneList* args = expr->arguments(); - ASSERT(args->length() == 1); - - VisitForAccumulatorValue(args->at(0)); - - Label materialize_true, materialize_false; - Label* if_true = NULL; - Label* if_false = NULL; - Label* fall_through = NULL; - context()->PrepareTest(&materialize_true, &materialize_false, - &if_true, &if_false, &fall_through); - - __ JumpIfSmi(r0, if_false); - __ CompareObjectType(r0, r1, r2, SYMBOL_TYPE); - PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - Split(eq, if_true, if_false, fall_through); - - context()->Plug(if_true, if_false); -} - - void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { ZoneList* args = expr->arguments(); ASSERT(args->length() == 1); @@ -4292,6 +4270,10 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); __ tst(r1, Operand(1 << Map::kIsUndetectable)); Split(eq, if_true, if_false, fall_through); + } else if (check->Equals(isolate()->heap()->symbol_string())) { + __ JumpIfSmi(r0, if_false); + __ CompareObjectType(r0, r0, r1, SYMBOL_TYPE); + Split(eq, if_true, if_false, fall_through); } else if (check->Equals(isolate()->heap()->boolean_string())) { __ CompareRoot(r0, Heap::kTrueValueRootIndex); __ b(eq, if_true); @@ -4324,10 +4306,6 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, __ CompareRoot(r0, Heap::kNullValueRootIndex); __ b(eq, if_true); } - if (FLAG_harmony_symbols) { - __ CompareObjectType(r0, r0, r1, SYMBOL_TYPE); - __ b(eq, if_true); - } // Check for JS objects => true. __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); __ b(lt, if_false); diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc index 38884ce0af..f2b65efe81 100644 --- a/deps/v8/src/arm/lithium-arm.cc +++ b/deps/v8/src/arm/lithium-arm.cc @@ -871,6 +871,35 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { LInstruction* instr = current->CompileToLithium(this); if (instr != NULL) { +#if DEBUG + // Make sure that the lithium instruction has either no fixed register + // constraints in temps or the result OR no uses that are only used at + // start. If this invariant doesn't hold, the register allocator can decide + // to insert a split of a range immediately before the instruction due to an + // already allocated register needing to be used for the instruction's fixed + // register constraint. In this case, The register allocator won't see an + // interference between the split child and the use-at-start (it would if + // the it was just a plain use), so it is free to move the split child into + // the same register that is used for the use-at-start. + // See https://code.google.com/p/chromium/issues/detail?id=201590 + if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) { + int fixed = 0; + int used_at_start = 0; + for (UseIterator it(instr); !it.Done(); it.Advance()) { + LUnallocated* operand = LUnallocated::cast(it.Current()); + if (operand->IsUsedAtStart()) ++used_at_start; + } + if (instr->Output() != NULL) { + if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; + } + for (TempIterator it(instr); !it.Done(); it.Advance()) { + LUnallocated* operand = LUnallocated::cast(it.Current()); + if (operand->HasFixedPolicy()) ++fixed; + } + ASSERT(fixed == 0 || used_at_start == 0); + } +#endif + if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { instr = AssignPointerMap(instr); } @@ -1115,7 +1144,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); return DefineFixedDouble(result, d2); } else { - LOperand* input = UseRegisterAtStart(instr->value()); + LOperand* input = UseRegister(instr->value()); LOperand* temp = (op == kMathRound) ? FixedTemp(d3) : NULL; LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); @@ -1711,12 +1740,6 @@ LInstruction* LChunkBuilder::DoClassOfTestAndBranch( } -LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { - LOperand* array = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LJSArrayLength(array)); -} - - LInstruction* LChunkBuilder::DoFixedArrayBaseLength( HFixedArrayBaseLength* instr) { LOperand* array = UseRegisterAtStart(instr->value()); @@ -1823,11 +1846,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { return AssignEnvironment(DefineAsRegister(res)); } else { ASSERT(to.IsInteger32()); - LOperand* value = UseRegisterAtStart(instr->value()); + LOperand* value = NULL; LInstruction* res = NULL; if (instr->value()->type().IsSmi()) { + value = UseRegisterAtStart(instr->value()); res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); } else { + value = UseRegister(instr->value()); LOperand* temp1 = TempRegister(); LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() : NULL; @@ -2205,7 +2230,7 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind( LOperand* new_map_reg = TempRegister(); LTransitionElementsKind* result = new(zone()) LTransitionElementsKind(object, new_map_reg, NULL); - return DefineSameAsFirst(result); + return result; } else if (FLAG_compiled_transitions) { LTransitionElementsKind* result = new(zone()) LTransitionElementsKind(object, NULL, NULL); diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h index f49e8ce4f8..207faf46e0 100644 --- a/deps/v8/src/arm/lithium-arm.h +++ b/deps/v8/src/arm/lithium-arm.h @@ -120,7 +120,6 @@ class LCodeGen; V(IsStringAndBranch) \ V(IsSmiAndBranch) \ V(IsUndetectableAndBranch) \ - V(JSArrayLength) \ V(Label) \ V(LazyBailout) \ V(LoadContextSlot) \ @@ -1165,19 +1164,6 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> { }; -class LJSArrayLength: public LTemplateInstruction<1, 1, 0> { - public: - explicit LJSArrayLength(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length") - DECLARE_HYDROGEN_ACCESSOR(JSArrayLength) -}; - - class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> { public: explicit LFixedArrayBaseLength(LOperand* value) { @@ -2114,7 +2100,7 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> { }; -class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> { +class LTransitionElementsKind: public LTemplateInstruction<0, 1, 2> { public: LTransitionElementsKind(LOperand* object, LOperand* new_map_temp, diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index 3ad86cfed3..7bb3535ff1 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -239,7 +239,7 @@ bool LCodeGen::GeneratePrologue() { __ str(r0, target); // Update the write barrier. This clobbers r3 and r0. __ RecordWriteContextSlot( - cp, target.offset(), r0, r3, kLRHasBeenSaved, kSaveFPRegs); + cp, target.offset(), r0, r3, GetLinkRegisterState(), kSaveFPRegs); } } Comment(";;; End allocate local context"); @@ -1918,13 +1918,6 @@ void LCodeGen::DoConstantT(LConstantT* instr) { } -void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { - Register result = ToRegister(instr->result()); - Register array = ToRegister(instr->value()); - __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); -} - - void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { Register result = ToRegister(instr->result()); Register array = ToRegister(instr->value()); @@ -2301,6 +2294,12 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } + if (expected.Contains(ToBooleanStub::SYMBOL)) { + // Symbol value -> true. + __ CompareInstanceType(map, ip, SYMBOL_TYPE); + __ b(eq, true_label); + } + if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { CpuFeatureScope scope(masm(), VFP2); // heap number -> false iff +0, -0, or NaN. @@ -3075,7 +3074,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { target.offset(), value, scratch, - kLRHasBeenSaved, + GetLinkRegisterState(), kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); @@ -4367,7 +4366,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { HeapObject::kMapOffset, scratch, temp, - kLRHasBeenSaved, + GetLinkRegisterState(), kSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); @@ -4386,7 +4385,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { offset, value, scratch, - kLRHasBeenSaved, + GetLinkRegisterState(), kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); @@ -4401,7 +4400,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { offset, value, object, - kLRHasBeenSaved, + GetLinkRegisterState(), kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); @@ -4602,7 +4601,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { __ RecordWrite(elements, key, value, - kLRHasBeenSaved, + GetLinkRegisterState(), kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); @@ -4654,7 +4653,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); // Write barrier. __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, - scratch, kLRHasBeenSaved, kDontSaveFPRegs); + scratch, GetLinkRegisterState(), kDontSaveFPRegs); } else if (FLAG_compiled_transitions) { PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); __ Move(r0, object_reg); @@ -4897,10 +4896,11 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { // Convert unsigned integer with specified number of leading zeroes in binary // representation to IEEE 754 double. -// Integer to convert is passed in register hiword. +// Integer to convert is passed in register src. // Resulting double is returned in registers hiword:loword. // This functions does not work correctly for 0. static void GenerateUInt2Double(MacroAssembler* masm, + Register src, Register hiword, Register loword, Register scratch, @@ -4914,13 +4914,13 @@ static void GenerateUInt2Double(MacroAssembler* masm, kBitsPerInt - mantissa_shift_for_hi_word; masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift)); if (mantissa_shift_for_hi_word > 0) { - masm->mov(loword, Operand(hiword, LSL, mantissa_shift_for_lo_word)); + masm->mov(loword, Operand(src, LSL, mantissa_shift_for_lo_word)); masm->orr(hiword, scratch, - Operand(hiword, LSR, mantissa_shift_for_hi_word)); + Operand(src, LSR, mantissa_shift_for_hi_word)); } else { masm->mov(loword, Operand::Zero()); masm->orr(hiword, scratch, - Operand(hiword, LSL, -mantissa_shift_for_hi_word)); + Operand(src, LSL, -mantissa_shift_for_hi_word)); } // If least significant bit of biased exponent was not 1 it was corrupted @@ -4969,17 +4969,17 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, __ vmov(flt_scratch, src); __ vcvt_f64_u32(dbl_scratch, flt_scratch); } else { - Label no_leading_zero, done; + Label no_leading_zero, convert_done; __ tst(src, Operand(0x80000000)); __ b(ne, &no_leading_zero); // Integer has one leading zeros. - GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); - __ b(&done); + GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 1); + __ b(&convert_done); __ bind(&no_leading_zero); - GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0); - __ b(&done); + GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 0); + __ bind(&convert_done); } } @@ -4996,10 +4996,18 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, // TODO(3095996): Put a valid pointer value in the stack slot where the result // register is stored, as this register is in the pointer map, but contains an // integer value. + if (!CpuFeatures::IsSupported(VFP2)) { + // Preserve sfpd_lo. + __ mov(r9, sfpd_lo); + } __ mov(ip, Operand::Zero()); __ StoreToSafepointRegisterSlot(ip, dst); CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); __ Move(dst, r0); + if (!CpuFeatures::IsSupported(VFP2)) { + // Restore sfpd_lo. + __ mov(sfpd_lo, r9); + } __ sub(dst, dst, Operand(kHeapObjectTag)); // Done. Put the value in dbl_scratch into the value of the allocated heap @@ -5671,12 +5679,12 @@ void LCodeGen::DoAllocate(LAllocate* instr) { __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); } else { Register size = ToRegister(instr->size()); - __ AllocateInNewSpace(size, - result, - scratch, - scratch2, - deferred->entry(), - flags); + __ Allocate(size, + result, + scratch, + scratch2, + deferred->entry(), + flags); } __ bind(deferred->exit()); @@ -6074,6 +6082,11 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, __ tst(ip, Operand(1 << Map::kIsUndetectable)); final_branch_condition = eq; + } else if (type_name->Equals(heap()->symbol_string())) { + __ JumpIfSmi(input, false_label); + __ CompareObjectType(input, input, scratch, SYMBOL_TYPE); + final_branch_condition = eq; + } else if (type_name->Equals(heap()->boolean_string())) { __ CompareRoot(input, Heap::kTrueValueRootIndex); __ b(eq, true_label); @@ -6108,15 +6121,8 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, __ CompareRoot(input, Heap::kNullValueRootIndex); __ b(eq, true_label); } - if (FLAG_harmony_symbols) { - __ CompareObjectType(input, input, scratch, SYMBOL_TYPE); - __ b(eq, true_label); - __ CompareInstanceType(input, scratch, - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); - } else { - __ CompareObjectType(input, input, scratch, - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); - } + __ CompareObjectType(input, input, scratch, + FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); __ b(lt, false_label); __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); __ b(gt, false_label); diff --git a/deps/v8/src/arm/lithium-codegen-arm.h b/deps/v8/src/arm/lithium-codegen-arm.h index d1f712ab80..686241db79 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.h +++ b/deps/v8/src/arm/lithium-codegen-arm.h @@ -87,6 +87,10 @@ class LCodeGen BASE_EMBEDDED { return !NeedsEagerFrame() && info()->is_deferred_calling(); } + LinkRegisterStatus GetLinkRegisterState() const { + return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved; + } + // Support for converting LOperands to assembler types. // LOperand must be a register. Register ToRegister(LOperand* op) const; diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index e0e77cfd33..bacf570c3b 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -708,15 +708,14 @@ void MacroAssembler::Ldrd(Register dst1, Register dst2, const MemOperand& src, Condition cond) { ASSERT(src.rm().is(no_reg)); ASSERT(!dst1.is(lr)); // r14. - ASSERT_EQ(0, dst1.code() % 2); - ASSERT_EQ(dst1.code() + 1, dst2.code()); // V8 does not use this addressing mode, so the fallback code // below doesn't support it yet. ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex)); // Generate two ldr instructions if ldrd is not available. - if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) { + if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() && + (dst1.code() % 2 == 0) && (dst1.code() + 1 == dst2.code())) { CpuFeatureScope scope(this, ARMv7); ldrd(dst1, dst2, src, cond); } else { @@ -750,15 +749,14 @@ void MacroAssembler::Strd(Register src1, Register src2, const MemOperand& dst, Condition cond) { ASSERT(dst.rm().is(no_reg)); ASSERT(!src1.is(lr)); // r14. - ASSERT_EQ(0, src1.code() % 2); - ASSERT_EQ(src1.code() + 1, src2.code()); // V8 does not use this addressing mode, so the fallback code // below doesn't support it yet. ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex)); // Generate two str instructions if strd is not available. - if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size()) { + if (CpuFeatures::IsSupported(ARMv7) && !predictable_code_size() && + (src1.code() % 2 == 0) && (src1.code() + 1 == src2.code())) { CpuFeatureScope scope(this, ARMv7); strd(src1, src2, dst, cond); } else { @@ -1671,13 +1669,12 @@ void MacroAssembler::Allocate(int object_size, } -void MacroAssembler::AllocateInNewSpace(Register object_size, - Register result, - Register scratch1, - Register scratch2, - Label* gc_required, - AllocationFlags flags) { - ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); +void MacroAssembler::Allocate(Register object_size, + Register result, + Register scratch1, + Register scratch2, + Label* gc_required, + AllocationFlags flags) { if (!FLAG_inline_new) { if (emit_debug_code()) { // Trash the registers to simulate an allocation failure. @@ -1703,20 +1700,20 @@ void MacroAssembler::AllocateInNewSpace(Register object_size, // The values must be adjacent in memory to allow the use of LDM. // Also, assert that the registers are numbered such that the values // are loaded in the correct order. - ExternalReference new_space_allocation_top = - ExternalReference::new_space_allocation_top_address(isolate()); - ExternalReference new_space_allocation_limit = - ExternalReference::new_space_allocation_limit_address(isolate()); + ExternalReference allocation_top = + AllocationUtils::GetAllocationTopReference(isolate(), flags); + ExternalReference allocation_limit = + AllocationUtils::GetAllocationLimitReference(isolate(), flags); intptr_t top = - reinterpret_cast(new_space_allocation_top.address()); + reinterpret_cast(allocation_top.address()); intptr_t limit = - reinterpret_cast(new_space_allocation_limit.address()); + reinterpret_cast(allocation_limit.address()); ASSERT((limit - top) == kPointerSize); ASSERT(result.code() < ip.code()); // Set up allocation top address. Register topaddr = scratch1; - mov(topaddr, Operand(new_space_allocation_top)); + mov(topaddr, Operand(allocation_top)); // This code stores a temporary value in ip. This is OK, as the code below // does not need ip for implicit literal generation. @@ -1739,6 +1736,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size, if ((flags & DOUBLE_ALIGNMENT) != 0) { // Align the next allocation. Storing the filler map without checking top is // always safe because the limit of the heap is always aligned. + ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); ASSERT(kPointerAlignment * 2 == kDoubleAlignment); and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC); Label aligned; @@ -1809,12 +1807,12 @@ void MacroAssembler::AllocateTwoByteString(Register result, and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); // Allocate two-byte string in new space. - AllocateInNewSpace(scratch1, - result, - scratch2, - scratch3, - gc_required, - TAG_OBJECT); + Allocate(scratch1, + result, + scratch2, + scratch3, + gc_required, + TAG_OBJECT); // Set the map, length and hash field. InitializeNewString(result, @@ -1840,12 +1838,12 @@ void MacroAssembler::AllocateAsciiString(Register result, and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); // Allocate ASCII string in new space. - AllocateInNewSpace(scratch1, - result, - scratch2, - scratch3, - gc_required, - TAG_OBJECT); + Allocate(scratch1, + result, + scratch2, + scratch3, + gc_required, + TAG_OBJECT); // Set the map, length and hash field. InitializeNewString(result, @@ -2499,9 +2497,9 @@ void MacroAssembler::TryInt32Floor(Register result, void MacroAssembler::ECMAConvertNumberToInt32(Register source, Register result, - Register scratch, - Register input_high, Register input_low, + Register input_high, + Register scratch, DwVfpRegister double_scratch1, DwVfpRegister double_scratch2) { if (CpuFeatures::IsSupported(VFP2)) { @@ -2578,24 +2576,26 @@ void MacroAssembler::ECMAToInt32NoVFP(Register result, Ubfx(scratch, input_high, HeapNumber::kExponentShift, HeapNumber::kExponentBits); - // Load scratch with exponent - 1. This is faster than loading - // with exponent because Bias + 1 = 1024 which is an *ARM* immediate value. - sub(scratch, scratch, Operand(HeapNumber::kExponentBias + 1)); + // Load scratch with exponent. + sub(scratch, scratch, Operand(HeapNumber::kExponentBias)); // If exponent is negative, 0 < input < 1, the result is 0. // If exponent is greater than or equal to 84, the 32 less significant // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits), // the result is 0. // This test also catch Nan and infinities which also return 0. - // Compare exponent with 84 (compare exponent - 1 with 83). - cmp(scratch, Operand(83)); + cmp(scratch, Operand(84)); // We do an unsigned comparison so negative numbers are treated as big // positive number and the two tests above are done in one test. b(hs, &out_of_range); - // Load scratch with 20 - exponent (load with 19 - (exponent - 1)). - rsb(scratch, scratch, Operand(19), SetCC); + // Load scratch with 20 - exponent. + rsb(scratch, scratch, Operand(20), SetCC); b(mi, &both); + // Test 0 and -0. + bic(result, input_high, Operand(HeapNumber::kSignMask)); + orr(result, result, Operand(input_low), SetCC); + b(eq, &done); // 0 <= exponent <= 20, shift only input_high. // Scratch contains: 20 - exponent. Ubfx(result, input_high, diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h index 5cbe995d76..958fcacb31 100644 --- a/deps/v8/src/arm/macro-assembler-arm.h +++ b/deps/v8/src/arm/macro-assembler-arm.h @@ -679,12 +679,12 @@ class MacroAssembler: public Assembler { Label* gc_required, AllocationFlags flags); - void AllocateInNewSpace(Register object_size, - Register result, - Register scratch1, - Register scratch2, - Label* gc_required, - AllocationFlags flags); + void Allocate(Register object_size, + Register result, + Register scratch1, + Register scratch2, + Label* gc_required, + AllocationFlags flags); // Undo allocation in new space. The object passed and objects allocated after // it will no longer be allocated. The caller must make sure that no pointers @@ -960,9 +960,9 @@ class MacroAssembler: public Assembler { // Exits with 'result' holding the answer. void ECMAConvertNumberToInt32(Register source, Register result, - Register scratch, - Register input_high, Register input_low, + Register input_high, + Register scratch, DwVfpRegister double_scratch1, DwVfpRegister double_scratch2); diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc index b7bc839059..2551e14e49 100644 --- a/deps/v8/src/arm/simulator-arm.cc +++ b/deps/v8/src/arm/simulator-arm.cc @@ -112,8 +112,8 @@ void ArmDebugger::Stop(Instruction* instr) { ASSERT(msg != NULL); // Update this stop description. - if (isWatchedStop(code) && !watched_stops[code].desc) { - watched_stops[code].desc = msg; + if (isWatchedStop(code) && !watched_stops_[code].desc) { + watched_stops_[code].desc = msg; } if (strlen(msg) > 0) { @@ -141,8 +141,8 @@ void ArmDebugger::Stop(Instruction* instr) { char* msg = *reinterpret_cast(sim_->get_pc() + Instruction::kInstrSize); // Update this stop description. - if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) { - sim_->watched_stops[code].desc = msg; + if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) { + sim_->watched_stops_[code].desc = msg; } // Print the stop message and code if it is not the default code. if (code != kMaxStopCode) { @@ -1880,14 +1880,14 @@ bool Simulator::isEnabledStop(uint32_t code) { ASSERT(code <= kMaxStopCode); // Unwatched stops are always enabled. return !isWatchedStop(code) || - !(watched_stops[code].count & kStopDisabledBit); + !(watched_stops_[code].count & kStopDisabledBit); } void Simulator::EnableStop(uint32_t code) { ASSERT(isWatchedStop(code)); if (!isEnabledStop(code)) { - watched_stops[code].count &= ~kStopDisabledBit; + watched_stops_[code].count &= ~kStopDisabledBit; } } @@ -1895,7 +1895,7 @@ void Simulator::EnableStop(uint32_t code) { void Simulator::DisableStop(uint32_t code) { ASSERT(isWatchedStop(code)); if (isEnabledStop(code)) { - watched_stops[code].count |= kStopDisabledBit; + watched_stops_[code].count |= kStopDisabledBit; } } @@ -1903,13 +1903,13 @@ void Simulator::DisableStop(uint32_t code) { void Simulator::IncreaseStopCounter(uint32_t code) { ASSERT(code <= kMaxStopCode); ASSERT(isWatchedStop(code)); - if ((watched_stops[code].count & ~(1 << 31)) == 0x7fffffff) { + if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { PrintF("Stop counter for code %i has overflowed.\n" "Enabling this code and reseting the counter to 0.\n", code); - watched_stops[code].count = 0; + watched_stops_[code].count = 0; EnableStop(code); } else { - watched_stops[code].count++; + watched_stops_[code].count++; } } @@ -1921,12 +1921,12 @@ void Simulator::PrintStopInfo(uint32_t code) { PrintF("Stop not watched."); } else { const char* state = isEnabledStop(code) ? "Enabled" : "Disabled"; - int32_t count = watched_stops[code].count & ~kStopDisabledBit; + int32_t count = watched_stops_[code].count & ~kStopDisabledBit; // Don't print the state of unused breakpoints. if (count != 0) { - if (watched_stops[code].desc) { + if (watched_stops_[code].desc) { PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", - code, code, state, count, watched_stops[code].desc); + code, code, state, count, watched_stops_[code].desc); } else { PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state, count); diff --git a/deps/v8/src/arm/simulator-arm.h b/deps/v8/src/arm/simulator-arm.h index 907a590665..b918ecf963 100644 --- a/deps/v8/src/arm/simulator-arm.h +++ b/deps/v8/src/arm/simulator-arm.h @@ -414,14 +414,14 @@ class Simulator { static const uint32_t kStopDisabledBit = 1 << 31; // A stop is enabled, meaning the simulator will stop when meeting the - // instruction, if bit 31 of watched_stops[code].count is unset. - // The value watched_stops[code].count & ~(1 << 31) indicates how many times + // instruction, if bit 31 of watched_stops_[code].count is unset. + // The value watched_stops_[code].count & ~(1 << 31) indicates how many times // the breakpoint was hit or gone through. struct StopCountAndDesc { uint32_t count; char* desc; }; - StopCountAndDesc watched_stops[kNumOfWatchedStops]; + StopCountAndDesc watched_stops_[kNumOfWatchedStops]; }; diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc index 3350c56c16..f2d45e190a 100644 --- a/deps/v8/src/arm/stub-cache-arm.cc +++ b/deps/v8/src/arm/stub-cache-arm.cc @@ -423,7 +423,7 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, // registers have their original values. void StubCompiler::GenerateStoreField(MacroAssembler* masm, Handle object, - int index, + LookupResult* lookup, Handle transition, Handle name, Register receiver_reg, @@ -436,16 +436,6 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, // r0 : value Label exit; - LookupResult lookup(masm->isolate()); - object->Lookup(*name, &lookup); - if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { - // In sloppy mode, we could just return the value and be done. However, we - // might be in strict mode, where we have to throw. Since we cannot tell, - // go into slow case unconditionally. - __ jmp(miss_label); - return; - } - // Check that the map of the object hasn't changed. CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS : REQUIRE_EXACT_MAP; @@ -460,8 +450,9 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, // Check that we are allowed to write this. if (!transition.is_null() && object->GetPrototype()->IsJSObject()) { JSObject* holder; - if (lookup.IsFound()) { - holder = lookup.holder(); + // holder == object indicates that no property was found. + if (lookup->holder() != *object) { + holder = lookup->holder(); } else { // Find the top object. holder = *object; @@ -469,8 +460,19 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, holder = JSObject::cast(holder->GetPrototype()); } while (holder->GetPrototype()->IsJSObject()); } - CheckPrototypes(object, receiver_reg, Handle(holder), name_reg, - scratch1, scratch2, name, miss_restore_name); + Register holder_reg = CheckPrototypes( + object, receiver_reg, Handle(holder), name_reg, + scratch1, scratch2, name, miss_restore_name); + // If no property was found, and the holder (the last object in the + // prototype chain) is in slow mode, we need to do a negative lookup on the + // holder. + if (lookup->holder() == *object && + !holder->HasFastProperties() && + !holder->IsJSGlobalProxy() && + !holder->IsJSGlobalObject()) { + GenerateDictionaryNegativeLookup( + masm, miss_restore_name, holder_reg, name, scratch1, scratch2); + } } // Stub never generated for non-global objects that require access @@ -492,6 +494,7 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, return; } + int index; if (!transition.is_null()) { // Update the map of the object. __ mov(scratch1, Operand(transition)); @@ -507,6 +510,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); + index = transition->instance_descriptors()->GetFieldIndex( + transition->LastAdded()); + } else { + index = lookup->GetFieldIndex().field_index(); } // Adjust for the number of properties stored in the object. Even in the @@ -2391,6 +2398,12 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, // Check that the object is a symbol. __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE); __ b(ne, &miss); + // Check that the maps starting from the prototype haven't changed. + GenerateDirectLoadGlobalFunctionPrototype( + masm(), Context::SYMBOL_FUNCTION_INDEX, r0, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + r0, holder, r3, r1, r4, name, &miss); break; case NUMBER_CHECK: { @@ -2982,7 +2995,7 @@ Handle ConstructStubCompiler::CompileConstructStub( __ cmp(r3, Operand(instance_size >> kPointerSizeLog2)); __ Check(eq, "Instance size of initial map changed."); #endif - __ AllocateInNewSpace(r3, r4, r5, r6, &generic_stub_call, SIZE_IN_WORDS); + __ Allocate(r3, r4, r5, r6, &generic_stub_call, SIZE_IN_WORDS); // Allocated the JSObject, now initialize the fields. Map is set to initial // map and properties and elements are set to empty fixed array. diff --git a/deps/v8/src/array.js b/deps/v8/src/array.js index 7cf744bedf..936d008012 100644 --- a/deps/v8/src/array.js +++ b/deps/v8/src/array.js @@ -38,22 +38,21 @@ var visited_arrays = new InternalArray(); // Gets a sorted array of array keys. Useful for operations on sparse // arrays. Dupes have not been removed. -function GetSortedArrayKeys(array, intervals) { - var length = intervals.length; - var keys = []; - for (var k = 0; k < length; k++) { - var key = intervals[k]; - if (key < 0) { - var j = -1 - key; - var limit = j + intervals[++k]; - for (; j < limit; j++) { - var e = array[j]; - if (!IS_UNDEFINED(e) || j in array) { - keys.push(j); - } +function GetSortedArrayKeys(array, indices) { + var keys = new InternalArray(); + if (IS_NUMBER(indices)) { + // It's an interval + var limit = indices; + for (var i = 0; i < limit; ++i) { + var e = array[i]; + if (!IS_UNDEFINED(e) || i in array) { + keys.push(i); } - } else { - // The case where key is undefined also ends here. + } + } else { + var length = indices.length; + for (var k = 0; k < length; ++k) { + var key = indices[k]; if (!IS_UNDEFINED(key)) { var e = array[key]; if (!IS_UNDEFINED(e) || key in array) { @@ -61,8 +60,8 @@ function GetSortedArrayKeys(array, intervals) { } } } + %_CallFunction(keys, function(a, b) { return a - b; }, ArraySort); } - %_CallFunction(keys, function(a, b) { return a - b; }, ArraySort); return keys; } @@ -217,34 +216,21 @@ function ConvertToLocaleString(e) { // special array operations to handle sparse arrays in a sensible fashion. function SmartSlice(array, start_i, del_count, len, deleted_elements) { // Move deleted elements to a new array (the return value from splice). - // Intervals array can contain keys and intervals. See comment in Concat. - var intervals = %GetArrayKeys(array, start_i + del_count); - var length = intervals.length; - for (var k = 0; k < length; k++) { - var key = intervals[k]; - if (key < 0) { - var j = -1 - key; - var interval_limit = j + intervals[++k]; - if (j < start_i) { - j = start_i; - } - for (; j < interval_limit; j++) { - // ECMA-262 15.4.4.12 line 10. The spec could also be - // interpreted such that %HasLocalProperty would be the - // appropriate test. We follow KJS in consulting the - // prototype. - var current = array[j]; - if (!IS_UNDEFINED(current) || j in array) { - deleted_elements[j - start_i] = current; - } + var indices = %GetArrayKeys(array, start_i + del_count); + if (IS_NUMBER(indices)) { + var limit = indices; + for (var i = start_i; i < limit; ++i) { + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + deleted_elements[i - start_i] = current; } - } else { + } + } else { + var length = indices.length; + for (var k = 0; k < length; ++k) { + var key = indices[k]; if (!IS_UNDEFINED(key)) { if (key >= start_i) { - // ECMA-262 15.4.4.12 line 10. The spec could also be - // interpreted such that %HasLocalProperty would be the - // appropriate test. We follow KJS in consulting the - // prototype. var current = array[key]; if (!IS_UNDEFINED(current) || key in array) { deleted_elements[key - start_i] = current; @@ -261,50 +247,32 @@ function SmartSlice(array, start_i, del_count, len, deleted_elements) { function SmartMove(array, start_i, del_count, len, num_additional_args) { // Move data to new array. var new_array = new InternalArray(len - del_count + num_additional_args); - var intervals = %GetArrayKeys(array, len); - var length = intervals.length; - for (var k = 0; k < length; k++) { - var key = intervals[k]; - if (key < 0) { - var j = -1 - key; - var interval_limit = j + intervals[++k]; - while (j < start_i && j < interval_limit) { - // The spec could also be interpreted such that - // %HasLocalProperty would be the appropriate test. We follow - // KJS in consulting the prototype. - var current = array[j]; - if (!IS_UNDEFINED(current) || j in array) { - new_array[j] = current; - } - j++; + var indices = %GetArrayKeys(array, len); + if (IS_NUMBER(indices)) { + var limit = indices; + for (var i = 0; i < start_i && i < limit; ++i) { + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + new_array[i] = current; } - j = start_i + del_count; - while (j < interval_limit) { - // ECMA-262 15.4.4.12 lines 24 and 41. The spec could also be - // interpreted such that %HasLocalProperty would be the - // appropriate test. We follow KJS in consulting the - // prototype. - var current = array[j]; - if (!IS_UNDEFINED(current) || j in array) { - new_array[j - del_count + num_additional_args] = current; - } - j++; + } + for (var i = start_i + del_count; i < limit; ++i) { + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + new_array[i - del_count + num_additional_args] = current; } - } else { + } + } else { + var length = indices.length; + for (var k = 0; k < length; ++k) { + var key = indices[k]; if (!IS_UNDEFINED(key)) { if (key < start_i) { - // The spec could also be interpreted such that - // %HasLocalProperty would be the appropriate test. We follow - // KJS in consulting the prototype. var current = array[key]; if (!IS_UNDEFINED(current) || key in array) { new_array[key] = current; } } else if (key >= start_i + del_count) { - // ECMA-262 15.4.4.12 lines 24 and 41. The spec could also - // be interpreted such that %HasLocalProperty would be the - // appropriate test. We follow KJS in consulting the - // prototype. var current = array[key]; if (!IS_UNDEFINED(current) || key in array) { new_array[key - del_count + num_additional_args] = current; @@ -887,24 +855,22 @@ function ArraySort(comparefn) { var max = 0; for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) { var indices = %GetArrayKeys(proto, length); - if (indices.length > 0) { - if (indices[0] == -1) { - // It's an interval. - var proto_length = indices[1]; - for (var i = 0; i < proto_length; i++) { - if (!obj.hasOwnProperty(i) && proto.hasOwnProperty(i)) { - obj[i] = proto[i]; - if (i >= max) { max = i + 1; } - } + if (IS_NUMBER(indices)) { + // It's an interval. + var proto_length = indices; + for (var i = 0; i < proto_length; i++) { + if (!obj.hasOwnProperty(i) && proto.hasOwnProperty(i)) { + obj[i] = proto[i]; + if (i >= max) { max = i + 1; } } - } else { - for (var i = 0; i < indices.length; i++) { - var index = indices[i]; - if (!IS_UNDEFINED(index) && - !obj.hasOwnProperty(index) && proto.hasOwnProperty(index)) { - obj[index] = proto[index]; - if (index >= max) { max = index + 1; } - } + } + } else { + for (var i = 0; i < indices.length; i++) { + var index = indices[i]; + if (!IS_UNDEFINED(index) && + !obj.hasOwnProperty(index) && proto.hasOwnProperty(index)) { + obj[index] = proto[index]; + if (index >= max) { max = index + 1; } } } } @@ -918,22 +884,20 @@ function ArraySort(comparefn) { var ShadowPrototypeElements = function(obj, from, to) { for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) { var indices = %GetArrayKeys(proto, to); - if (indices.length > 0) { - if (indices[0] == -1) { - // It's an interval. - var proto_length = indices[1]; - for (var i = from; i < proto_length; i++) { - if (proto.hasOwnProperty(i)) { - obj[i] = void 0; - } + if (IS_NUMBER(indices)) { + // It's an interval. + var proto_length = indices; + for (var i = from; i < proto_length; i++) { + if (proto.hasOwnProperty(i)) { + obj[i] = void 0; } - } else { - for (var i = 0; i < indices.length; i++) { - var index = indices[i]; - if (!IS_UNDEFINED(index) && from <= index && - proto.hasOwnProperty(index)) { - obj[index] = void 0; - } + } + } else { + for (var i = 0; i < indices.length; i++) { + var index = indices[i]; + if (!IS_UNDEFINED(index) && from <= index && + proto.hasOwnProperty(index)) { + obj[index] = void 0; } } } @@ -1284,18 +1248,15 @@ function ArrayIndexOf(element, index) { var min = index; var max = length; if (UseSparseVariant(this, length, IS_ARRAY(this))) { - var intervals = %GetArrayKeys(this, length); - if (intervals.length == 2 && intervals[0] < 0) { - // A single interval. - var intervalMin = -(intervals[0] + 1); - var intervalMax = intervalMin + intervals[1]; - if (min < intervalMin) min = intervalMin; - max = intervalMax; // Capped by length already. + var indices = %GetArrayKeys(this, length); + if (IS_NUMBER(indices)) { + // It's an interval. + max = indices; // Capped by length already. // Fall through to loop below. } else { - if (intervals.length == 0) return -1; + if (indices.length == 0) return -1; // Get all the keys in sorted order. - var sortedKeys = GetSortedArrayKeys(this, intervals); + var sortedKeys = GetSortedArrayKeys(this, indices); var n = sortedKeys.length; var i = 0; while (i < n && sortedKeys[i] < index) i++; @@ -1345,18 +1306,15 @@ function ArrayLastIndexOf(element, index) { var min = 0; var max = index; if (UseSparseVariant(this, length, IS_ARRAY(this))) { - var intervals = %GetArrayKeys(this, index + 1); - if (intervals.length == 2 && intervals[0] < 0) { - // A single interval. - var intervalMin = -(intervals[0] + 1); - var intervalMax = intervalMin + intervals[1]; - if (min < intervalMin) min = intervalMin; - max = intervalMax; // Capped by index already. + var indices = %GetArrayKeys(this, index + 1); + if (IS_NUMBER(indices)) { + // It's an interval. + max = indices; // Capped by index already. // Fall through to loop below. } else { - if (intervals.length == 0) return -1; + if (indices.length == 0) return -1; // Get all the keys in sorted order. - var sortedKeys = GetSortedArrayKeys(this, intervals); + var sortedKeys = GetSortedArrayKeys(this, indices); var i = sortedKeys.length - 1; while (i >= 0) { var key = sortedKeys[i]; diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc index 8536ca006f..deef28b1f3 100644 --- a/deps/v8/src/assembler.cc +++ b/deps/v8/src/assembler.cc @@ -927,20 +927,9 @@ void ExternalReference::InitializeMathExpData() { math_exp_log_table_array = new double[kTableSize]; for (int i = 0; i < kTableSize; i++) { double value = pow(2, i / kTableSizeDouble); - uint64_t bits = BitCast(value); bits &= (static_cast(1) << 52) - 1; double mantissa = BitCast(bits); - - // - uint64_t doublebits; - memcpy(&doublebits, &value, sizeof doublebits); - doublebits &= (static_cast(1) << 52) - 1; - double mantissa2; - memcpy(&mantissa2, &doublebits, sizeof mantissa2); - CHECK_EQ(mantissa, mantissa2); - // - math_exp_log_table_array[i] = mantissa; } diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc index 712bfd1b9d..7d7a5b247d 100644 --- a/deps/v8/src/ast.cc +++ b/deps/v8/src/ast.cc @@ -128,7 +128,8 @@ Assignment::Assignment(Isolate* isolate, pos_(pos), binary_operation_(NULL), assignment_id_(GetNextId(isolate)), - is_monomorphic_(false) { } + is_monomorphic_(false), + store_mode_(STANDARD_STORE) { } Token::Value Assignment::binary_op() const { @@ -413,12 +414,9 @@ void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle, is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this); receiver_types_.Clear(); if (key()->IsPropertyName()) { - ArrayLengthStub array_stub(Code::LOAD_IC); FunctionPrototypeStub proto_stub(Code::LOAD_IC); StringLengthStub string_stub(Code::LOAD_IC, false); - if (oracle->LoadIsStub(this, &array_stub)) { - is_array_length_ = true; - } else if (oracle->LoadIsStub(this, &string_stub)) { + if (oracle->LoadIsStub(this, &string_stub)) { is_string_length_ = true; } else if (oracle->LoadIsStub(this, &proto_stub)) { is_function_prototype_ = true; @@ -455,9 +453,11 @@ void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle, } else if (is_monomorphic_) { // Record receiver type for monomorphic keyed stores. receiver_types_.Add(oracle->StoreMonomorphicReceiverType(id), zone); + store_mode_ = oracle->GetStoreMode(id); } else if (oracle->StoreIsPolymorphic(id)) { receiver_types_.Reserve(kMaxKeyedPolymorphism, zone); oracle->CollectKeyedReceiverTypes(id, &receiver_types_); + store_mode_ = oracle->GetStoreMode(id); } } @@ -475,6 +475,7 @@ void CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle, receiver_types_.Reserve(kMaxKeyedPolymorphism, zone); oracle->CollectKeyedReceiverTypes(id, &receiver_types_); } + store_mode_ = oracle->GetStoreMode(id); } @@ -1061,6 +1062,7 @@ DONT_OPTIMIZE_NODE(ModuleVariable) DONT_OPTIMIZE_NODE(ModulePath) DONT_OPTIMIZE_NODE(ModuleUrl) DONT_OPTIMIZE_NODE(ModuleStatement) +DONT_OPTIMIZE_NODE(Yield) DONT_OPTIMIZE_NODE(WithStatement) DONT_OPTIMIZE_NODE(TryCatchStatement) DONT_OPTIMIZE_NODE(TryFinallyStatement) diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h index 5debc74ebb..dddfc835fd 100644 --- a/deps/v8/src/ast.h +++ b/deps/v8/src/ast.h @@ -102,6 +102,7 @@ namespace internal { V(ObjectLiteral) \ V(ArrayLiteral) \ V(Assignment) \ + V(Yield) \ V(Throw) \ V(Property) \ V(Call) \ @@ -119,6 +120,10 @@ namespace internal { STATEMENT_NODE_LIST(V) \ EXPRESSION_NODE_LIST(V) +#ifdef WIN32 +#undef Yield +#endif + // Forward declarations class AstConstructionVisitor; template class AstNodeFactory; @@ -349,6 +354,10 @@ class Expression: public AstNode { ASSERT(types != NULL && types->length() == 1); return types->at(0); } + virtual KeyedAccessStoreMode GetStoreMode() { + UNREACHABLE(); + return STANDARD_STORE; + } BailoutId id() const { return id_; } TypeFeedbackId test_id() const { return test_id_; } @@ -1481,7 +1490,9 @@ class Property: public Expression { void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone); virtual bool IsMonomorphic() { return is_monomorphic_; } virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } - bool IsArrayLength() { return is_array_length_; } + virtual KeyedAccessStoreMode GetStoreMode() { + return STANDARD_STORE; + } bool IsUninitialized() { return is_uninitialized_; } TypeFeedbackId PropertyFeedbackId() { return reuse(id()); } @@ -1497,7 +1508,6 @@ class Property: public Expression { load_id_(GetNextId(isolate)), is_monomorphic_(false), is_uninitialized_(false), - is_array_length_(false), is_string_length_(false), is_string_access_(false), is_function_prototype_(false) { } @@ -1511,7 +1521,6 @@ class Property: public Expression { SmallMapList receiver_types_; bool is_monomorphic_ : 1; bool is_uninitialized_ : 1; - bool is_array_length_ : 1; bool is_string_length_ : 1; bool is_string_access_ : 1; bool is_function_prototype_ : 1; @@ -1773,6 +1782,9 @@ class CountOperation: public Expression { void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe); virtual bool IsMonomorphic() { return is_monomorphic_; } virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } + virtual KeyedAccessStoreMode GetStoreMode() { + return store_mode_; + } BailoutId AssignmentId() const { return assignment_id_; } @@ -1788,6 +1800,8 @@ class CountOperation: public Expression { : Expression(isolate), op_(op), is_prefix_(is_prefix), + is_monomorphic_(false), + store_mode_(STANDARD_STORE), expression_(expr), pos_(pos), assignment_id_(GetNextId(isolate)), @@ -1795,8 +1809,9 @@ class CountOperation: public Expression { private: Token::Value op_; - bool is_prefix_; - bool is_monomorphic_; + bool is_prefix_ : 1; + bool is_monomorphic_ : 1; + KeyedAccessStoreMode store_mode_: 4; Expression* expression_; int pos_; const BailoutId assignment_id_; @@ -1909,6 +1924,9 @@ class Assignment: public Expression { void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone); virtual bool IsMonomorphic() { return is_monomorphic_; } virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } + virtual KeyedAccessStoreMode GetStoreMode() { + return store_mode_; + } protected: Assignment(Isolate* isolate, @@ -1934,11 +1952,37 @@ class Assignment: public Expression { BinaryOperation* binary_operation_; const BailoutId assignment_id_; - bool is_monomorphic_; + bool is_monomorphic_ : 1; + KeyedAccessStoreMode store_mode_ : 4; SmallMapList receiver_types_; }; +class Yield: public Expression { + public: + DECLARE_NODE_TYPE(Yield) + + Expression* expression() const { return expression_; } + bool is_delegating_yield() const { return is_delegating_yield_; } + virtual int position() const { return pos_; } + + protected: + Yield(Isolate* isolate, + Expression* expression, + bool is_delegating_yield, + int pos) + : Expression(isolate), + expression_(expression), + is_delegating_yield_(is_delegating_yield), + pos_(pos) { } + + private: + Expression* expression_; + bool is_delegating_yield_; + int pos_; +}; + + class Throw: public Expression { public: DECLARE_NODE_TYPE(Throw) @@ -1979,6 +2023,11 @@ class FunctionLiteral: public Expression { kNotParenthesized }; + enum IsGeneratorFlag { + kIsGenerator, + kNotGenerator + }; + DECLARE_NODE_TYPE(FunctionLiteral) Handle name() const { return name_; } @@ -2039,6 +2088,10 @@ class FunctionLiteral: public Expression { bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized); } + bool is_generator() { + return IsGenerator::decode(bitfield_) == kIsGenerator; + } + int ast_node_count() { return ast_properties_.node_count(); } AstProperties::Flags* flags() { return ast_properties_.flags(); } void set_ast_properties(AstProperties* ast_properties) { @@ -2059,7 +2112,8 @@ class FunctionLiteral: public Expression { Type type, ParameterFlag has_duplicate_parameters, IsFunctionFlag is_function, - IsParenthesizedFlag is_parenthesized) + IsParenthesizedFlag is_parenthesized, + IsGeneratorFlag is_generator) : Expression(isolate), name_(name), scope_(scope), @@ -2079,7 +2133,8 @@ class FunctionLiteral: public Expression { Pretenure::encode(false) | HasDuplicateParameters::encode(has_duplicate_parameters) | IsFunction::encode(is_function) | - IsParenthesized::encode(is_parenthesized); + IsParenthesized::encode(is_parenthesized) | + IsGenerator::encode(is_generator); } private: @@ -2104,6 +2159,7 @@ class FunctionLiteral: public Expression { class HasDuplicateParameters: public BitField {}; class IsFunction: public BitField {}; class IsParenthesized: public BitField {}; + class IsGenerator: public BitField {}; }; @@ -2902,6 +2958,12 @@ class AstNodeFactory BASE_EMBEDDED { VISIT_AND_RETURN(Assignment, assign) } + Yield* NewYield(Expression* expression, bool is_delegating_yield, int pos) { + Yield* yield = + new(zone_) Yield(isolate_, expression, is_delegating_yield, pos); + VISIT_AND_RETURN(Yield, yield) + } + Throw* NewThrow(Expression* exception, int pos) { Throw* t = new(zone_) Throw(isolate_, exception, pos); VISIT_AND_RETURN(Throw, t) @@ -2920,13 +2982,14 @@ class AstNodeFactory BASE_EMBEDDED { FunctionLiteral::ParameterFlag has_duplicate_parameters, FunctionLiteral::Type type, FunctionLiteral::IsFunctionFlag is_function, - FunctionLiteral::IsParenthesizedFlag is_parenthesized) { + FunctionLiteral::IsParenthesizedFlag is_parenthesized, + FunctionLiteral::IsGeneratorFlag is_generator) { FunctionLiteral* lit = new(zone_) FunctionLiteral( isolate_, name, scope, body, materialized_literal_count, expected_property_count, handler_count, has_only_simple_this_property_assignments, this_property_assignments, parameter_count, type, has_duplicate_parameters, is_function, - is_parenthesized); + is_parenthesized, is_generator); // Top-level literal doesn't count for the AST's properties. if (is_function == FunctionLiteral::kIsFunction) { visitor_.VisitFunctionLiteral(lit); diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 58b2ad0387..f57a1f6fd8 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -303,9 +303,9 @@ Handle Bootstrapper::CreateEnvironment( v8::ExtensionConfiguration* extensions) { HandleScope scope(isolate_); Genesis genesis(isolate_, global_object, global_template, extensions); - Handle context(isolate_->global_handles()->Create(*genesis.result())); - Handle env = Handle::cast(context); - if (!env.is_null()) { + if (!genesis.result().is_null()) { + Handle ctx(isolate_->global_handles()->Create(*genesis.result())); + Handle env = Handle::cast(ctx); if (InstallExtensions(env, extensions)) { return env; } @@ -1280,7 +1280,17 @@ void Genesis::InitializeExperimentalGlobal() { Handle global = Handle(native_context()->global_object()); // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no - // longer need to live behind a flag, so functions get added to the snapshot. + // longer need to live behind flags, so functions get added to the snapshot. + + if (FLAG_harmony_symbols) { + // --- S y m b o l --- + Handle symbol_fun = + InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize, + isolate()->initial_object_prototype(), + Builtins::kIllegal, true); + native_context()->set_symbol_function(*symbol_fun); + } + if (FLAG_harmony_collections) { { // -- S e t Handle prototype = @@ -1301,6 +1311,16 @@ void Genesis::InitializeExperimentalGlobal() { prototype, Builtins::kIllegal, true); } } + + if (FLAG_harmony_typed_arrays) { + { // -- A r r a y B u f f e r + Handle prototype = + factory()->NewJSObject(isolate()->object_function(), TENURED); + InstallFunction(global, "__ArrayBuffer", JS_ARRAY_BUFFER_TYPE, + JSArrayBuffer::kSize, prototype, + Builtins::kIllegal, true); + } + } } @@ -1436,9 +1456,6 @@ void Genesis::InstallNativeFunctions() { } void Genesis::InstallExperimentalNativeFunctions() { - if (FLAG_harmony_symbols) { - INSTALL_NATIVE(JSObject, "SymbolDelegate", symbol_delegate); - } if (FLAG_harmony_proxies) { INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap); INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap); @@ -1911,6 +1928,11 @@ bool Genesis::InstallExperimentalNatives() { "native object-observe.js") == 0) { if (!CompileExperimentalBuiltin(isolate(), i)) return false; } + if (FLAG_harmony_typed_arrays && + strcmp(ExperimentalNatives::GetScriptName(i).start(), + "native typedarray.js") == 0) { + if (!CompileExperimentalBuiltin(isolate(), i)) return false; + } } InstallExperimentalNativeFunctions(); diff --git a/deps/v8/src/code-stubs-hydrogen.cc b/deps/v8/src/code-stubs-hydrogen.cc index ae198bc249..ee903aef1c 100644 --- a/deps/v8/src/code-stubs-hydrogen.cc +++ b/deps/v8/src/code-stubs-hydrogen.cc @@ -106,7 +106,8 @@ bool CodeStubGraphBuilderBase::BuildGraph() { Zone* zone = this->zone(); int param_count = descriptor_->register_param_count_; HEnvironment* start_environment = graph()->start_environment(); - HBasicBlock* next_block = CreateBasicBlock(start_environment); + HBasicBlock* next_block = + CreateBasicBlock(start_environment, BailoutId::StubEntry()); current_block()->Goto(next_block); next_block->SetJoinId(BailoutId::StubEntry()); set_current_block(next_block); @@ -128,7 +129,8 @@ bool CodeStubGraphBuilderBase::BuildGraph() { if (descriptor_->stack_parameter_count_ != NULL) { ASSERT(descriptor_->environment_length() == (param_count + 1)); stack_parameter_count = new(zone) HParameter(param_count, - HParameter::REGISTER_PARAMETER); + HParameter::REGISTER_PARAMETER, + Representation::Integer32()); // it's essential to bind this value to the environment in case of deopt start_environment->Bind(param_count, stack_parameter_count); AddInstruction(stack_parameter_count); @@ -146,13 +148,26 @@ bool CodeStubGraphBuilderBase::BuildGraph() { AddSimulate(BailoutId::StubEntry()); HValue* return_value = BuildCodeStub(); + + // We might have extra expressions to pop from the stack in addition to the + // arguments above + HInstruction* stack_pop_count = stack_parameter_count; + if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { + HInstruction* amount = graph()->GetConstant1(); + stack_pop_count = AddInstruction( + HAdd::New(zone, context_, stack_parameter_count, amount)); + stack_pop_count->ChangeRepresentation(Representation::Integer32()); + stack_pop_count->ClearFlag(HValue::kCanOverflow); + } + HReturn* hreturn_instruction = new(zone) HReturn(return_value, context_, - stack_parameter_count); + stack_pop_count); current_block()->Finish(hreturn_instruction); return true; } + template class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { public: @@ -165,6 +180,14 @@ class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { }; +template +static Handle DoGenerateCode(Stub* stub) { + CodeStubGraphBuilder builder(stub); + LChunk* chunk = OptimizeGraph(builder.CreateGraph()); + return chunk->Codegen(Code::COMPILED_STUB); +} + + template <> HValue* CodeStubGraphBuilder::BuildCodeStub() { Zone* zone = this->zone(); @@ -176,7 +199,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { NULL, FAST_ELEMENTS)); - CheckBuilder builder(this, BailoutId::StubEntry()); + CheckBuilder builder(this); builder.CheckNotUndefined(boilerplate); int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; @@ -216,9 +239,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { Handle FastCloneShallowObjectStub::GenerateCode() { - CodeStubGraphBuilder builder(this); - LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return DoGenerateCode(this); } @@ -227,16 +248,30 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* load = BuildUncheckedMonomorphicElementAccess( GetParameter(0), GetParameter(1), NULL, NULL, casted_stub()->is_js_array(), casted_stub()->elements_kind(), - false, Representation::Tagged()); - AddInstruction(load); + false, STANDARD_STORE, Representation::Tagged()); return load; } Handle KeyedLoadFastElementStub::GenerateCode() { - CodeStubGraphBuilder builder(this); - LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return DoGenerateCode(this); +} + + +template <> +HValue* CodeStubGraphBuilder::BuildCodeStub() { + BuildUncheckedMonomorphicElementAccess( + GetParameter(0), GetParameter(1), GetParameter(2), NULL, + casted_stub()->is_js_array(), casted_stub()->elements_kind(), + true, casted_stub()->store_mode(), Representation::Tagged()); + AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE); + + return GetParameter(2); +} + + +Handle KeyedStoreFastElementStub::GenerateCode() { + return DoGenerateCode(this); } @@ -252,31 +287,19 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { AddInstruction(new(zone) HTrapAllocationMemento(js_array)); HInstruction* array_length = - AddInstruction(new(zone) HJSArrayLength(js_array, - js_array, - HType::Smi())); + AddInstruction(HLoadNamedField::NewArrayLength( + zone, js_array, js_array, HType::Smi())); - Heap* heap = isolate()->heap(); - const int kMinFreeNewSpaceAfterGC = - ((heap->InitialSemiSpaceSize() - sizeof(FixedArrayBase)) / 2) / - kDoubleSize; - - HConstant* max_alloc_size = - new(zone) HConstant(kMinFreeNewSpaceAfterGC, Representation::Integer32()); - AddInstruction(max_alloc_size); - // Since we're forcing Integer32 representation for this HBoundsCheck, - // there's no need to Smi-check the index. - AddInstruction( - new(zone) HBoundsCheck(array_length, max_alloc_size, - DONT_ALLOW_SMI_KEY, Representation::Integer32())); + ElementsKind to_kind = casted_stub()->to_kind(); + BuildNewSpaceArrayCheck(array_length, to_kind); - IfBuilder if_builder(this, BailoutId::StubEntry()); + IfBuilder if_builder(this); - if_builder.BeginTrue(array_length, graph()->GetConstant0(), Token::EQ); + if_builder.BeginIf(array_length, graph()->GetConstant0(), Token::EQ); // Nothing to do, just change the map. - if_builder.BeginFalse(); + if_builder.BeginElse(); HInstruction* elements = AddInstruction(new(zone) HLoadElements(js_array, js_array)); @@ -284,37 +307,14 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* elements_length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); - ElementsKind to_kind = casted_stub()->to_kind(); HValue* new_elements = BuildAllocateElements(context(), to_kind, elements_length); - // Fast elements kinds need to be initialized in case statements below cause a - // garbage collection. - Factory* factory = isolate()->factory(); - - ASSERT(!IsFastSmiElementsKind(to_kind)); - double nan_double = FixedDoubleArray::hole_nan_as_double(); - HValue* hole = IsFastObjectElementsKind(to_kind) - ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), - Representation::Tagged())) - : AddInstruction(new(zone) HConstant(nan_double, - Representation::Double())); - - LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement, - BailoutId::StubEntry()); - - HValue* zero = graph()->GetConstant0(); - HValue* start = IsFastElementsKind(to_kind) ? zero : array_length; - HValue* key = builder.BeginBody(start, elements_length, Token::LT); - - AddInstruction(new(zone) HStoreKeyed(new_elements, key, hole, to_kind)); - AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE); - - builder.EndBody(); - BuildCopyElements(context(), elements, casted_stub()->from_kind(), new_elements, - to_kind, array_length); + to_kind, array_length, elements_length); + + Factory* factory = isolate()->factory(); AddInstruction(new(zone) HStoreNamedField(js_array, factory->elements_field_string(), @@ -331,6 +331,11 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { } +Handle TransitionElementsKindStub::GenerateCode() { + return DoGenerateCode(this); +} + + template <> HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* deopt = new(zone()) HSoftDeoptimize(); @@ -341,9 +346,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { Handle ArrayNoArgumentConstructorStub::GenerateCode() { - CodeStubGraphBuilder builder(this); - LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return DoGenerateCode(this); } @@ -357,17 +360,8 @@ HValue* CodeStubGraphBuilder:: } -Handle TransitionElementsKindStub::GenerateCode() { - CodeStubGraphBuilder builder(this); - LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); -} - - Handle ArraySingleArgumentConstructorStub::GenerateCode() { - CodeStubGraphBuilder builder(this); - LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return DoGenerateCode(this); } @@ -381,9 +375,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { Handle ArrayNArgumentsConstructorStub::GenerateCode() { - CodeStubGraphBuilder builder(this); - LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return DoGenerateCode(this); } } } // namespace v8::internal diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc index 95bc1e99cc..eff0f7f1cd 100644 --- a/deps/v8/src/code-stubs.cc +++ b/deps/v8/src/code-stubs.cc @@ -510,6 +510,7 @@ void ToBooleanStub::Types::Print(StringStream* stream) const { if (Contains(SMI)) stream->Add("Smi"); if (Contains(SPEC_OBJECT)) stream->Add("SpecObject"); if (Contains(STRING)) stream->Add("String"); + if (Contains(SYMBOL)) stream->Add("Symbol"); if (Contains(HEAP_NUMBER)) stream->Add("HeapNumber"); } @@ -549,6 +550,9 @@ bool ToBooleanStub::Types::Record(Handle object) { Add(STRING); return !object->IsUndetectableObject() && String::cast(*object)->length() != 0; + } else if (object->IsSymbol()) { + Add(SYMBOL); + return true; } else if (object->IsHeapNumber()) { ASSERT(!object->IsUndetectableObject()); Add(HEAP_NUMBER); @@ -565,6 +569,7 @@ bool ToBooleanStub::Types::Record(Handle object) { bool ToBooleanStub::Types::NeedsMap() const { return Contains(ToBooleanStub::SPEC_OBJECT) || Contains(ToBooleanStub::STRING) + || Contains(ToBooleanStub::SYMBOL) || Contains(ToBooleanStub::HEAP_NUMBER); } @@ -614,10 +619,8 @@ void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) { void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { - int i = 0; - for (; i <= StubFailureTrampolineStub::kMaxExtraExpressionStackCount; ++i) { - StubFailureTrampolineStub(i).GetCode(isolate); - } + StubFailureTrampolineStub(NOT_JS_FUNCTION_STUB_MODE).GetCode(isolate); + StubFailureTrampolineStub(JS_FUNCTION_STUB_MODE).GetCode(isolate); } diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h index e91b241579..99ff5154e1 100644 --- a/deps/v8/src/code-stubs.h +++ b/deps/v8/src/code-stubs.h @@ -47,7 +47,6 @@ namespace internal { V(Compare) \ V(CompareIC) \ V(MathPow) \ - V(ArrayLength) \ V(StringLength) \ V(FunctionPrototype) \ V(StoreArrayLength) \ @@ -259,15 +258,17 @@ class PlatformCodeStub : public CodeStub { }; +enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; + struct CodeStubInterfaceDescriptor { CodeStubInterfaceDescriptor() : register_param_count_(-1), stack_parameter_count_(NULL), - extra_expression_stack_count_(0), + function_mode_(NOT_JS_FUNCTION_STUB_MODE), register_params_(NULL) { } int register_param_count_; const Register* stack_parameter_count_; - int extra_expression_stack_count_; + StubFunctionMode function_mode_; Register* register_params_; Address deoptimization_handler_; @@ -597,16 +598,6 @@ class ICStub: public PlatformCodeStub { }; -class ArrayLengthStub: public ICStub { - public: - explicit ArrayLengthStub(Code::Kind kind) : ICStub(kind) { } - virtual void Generate(MacroAssembler* masm); - - private: - virtual CodeStub::Major MajorKey() { return ArrayLength; } -}; - - class FunctionPrototypeStub: public ICStub { public: explicit FunctionPrototypeStub(Code::Kind kind) : ICStub(kind) { } @@ -1312,6 +1303,47 @@ class KeyedLoadFastElementStub : public HydrogenCodeStub { }; +class KeyedStoreFastElementStub : public HydrogenCodeStub { + public: + KeyedStoreFastElementStub(bool is_js_array, + ElementsKind elements_kind, + KeyedAccessStoreMode mode) { + bit_field_ = ElementsKindBits::encode(elements_kind) | + IsJSArrayBits::encode(is_js_array) | + StoreModeBits::encode(mode); + } + + Major MajorKey() { return KeyedStoreElement; } + int MinorKey() { return bit_field_; } + + bool is_js_array() const { + return IsJSArrayBits::decode(bit_field_); + } + + ElementsKind elements_kind() const { + return ElementsKindBits::decode(bit_field_); + } + + KeyedAccessStoreMode store_mode() const { + return StoreModeBits::decode(bit_field_); + } + + virtual Handle GenerateCode(); + + virtual void InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor); + + private: + class ElementsKindBits: public BitField {}; + class StoreModeBits: public BitField {}; + class IsJSArrayBits: public BitField {}; + uint32_t bit_field_; + + DISALLOW_COPY_AND_ASSIGN(KeyedStoreFastElementStub); +}; + + class TransitionElementsKindStub : public HydrogenCodeStub { public: TransitionElementsKindStub(ElementsKind from_kind, @@ -1447,6 +1479,7 @@ class ToBooleanStub: public PlatformCodeStub { SMI, SPEC_OBJECT, STRING, + SYMBOL, HEAP_NUMBER, NUMBER_OF_TYPES }; @@ -1570,10 +1603,8 @@ class StoreArrayLiteralElementStub : public PlatformCodeStub { class StubFailureTrampolineStub : public PlatformCodeStub { public: - static const int kMaxExtraExpressionStackCount = 1; - - explicit StubFailureTrampolineStub(int extra_expression_stack_count) - : extra_expression_stack_count_(extra_expression_stack_count) {} + explicit StubFailureTrampolineStub(StubFunctionMode function_mode) + : function_mode_(function_mode) {} virtual bool IsPregenerated() { return true; } @@ -1581,11 +1612,11 @@ class StubFailureTrampolineStub : public PlatformCodeStub { private: Major MajorKey() { return StubFailureTrampoline; } - int MinorKey() { return extra_expression_stack_count_; } + int MinorKey() { return static_cast(function_mode_); } void Generate(MacroAssembler* masm); - int extra_expression_stack_count_; + StubFunctionMode function_mode_; DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); }; diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 2c4dae5d4e..6f9b901d9f 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -1121,6 +1121,7 @@ void Compiler::SetFunctionInfo(Handle function_info, function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); function_info->set_dont_cache(lit->flags()->Contains(kDontCache)); + function_info->set_is_generator(lit->is_generator()); } diff --git a/deps/v8/src/contexts.h b/deps/v8/src/contexts.h index cd7ed6adc5..a0ba2f7eb5 100644 --- a/deps/v8/src/contexts.h +++ b/deps/v8/src/contexts.h @@ -103,6 +103,7 @@ enum BindingFlags { V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \ V(STRING_FUNCTION_INDEX, JSFunction, string_function) \ V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \ + V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \ V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \ V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \ V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \ @@ -156,7 +157,6 @@ enum BindingFlags { V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \ V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \ error_message_for_code_gen_from_strings) \ - V(SYMBOL_DELEGATE_INDEX, JSObject, symbol_delegate) \ V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \ to_complete_property_descriptor) \ V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \ @@ -251,6 +251,7 @@ class Context: public FixedArray { NUMBER_FUNCTION_INDEX, STRING_FUNCTION_INDEX, STRING_FUNCTION_PROTOTYPE_MAP_INDEX, + SYMBOL_FUNCTION_INDEX, OBJECT_FUNCTION_INDEX, INTERNAL_ARRAY_FUNCTION_INDEX, ARRAY_FUNCTION_INDEX, @@ -287,7 +288,6 @@ class Context: public FixedArray { EMBEDDER_DATA_INDEX, ALLOW_CODE_GEN_FROM_STRINGS_INDEX, ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, - SYMBOL_DELEGATE_INDEX, TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, DERIVED_HAS_TRAP_INDEX, DERIVED_GET_TRAP_INDEX, diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc index 805a0cf1ad..b57e3907ce 100644 --- a/deps/v8/src/d8.cc +++ b/deps/v8/src/d8.cc @@ -227,11 +227,13 @@ bool Shell::ExecuteString(Isolate* isolate, } #if !defined(V8_SHARED) } else { + v8::TryCatch try_catch; Context::Scope context_scope(utility_context_); Handle global = utility_context_->Global(); Handle fun = global->Get(String::New("Stringify")); Handle argv[1] = { result }; Handle s = Handle::Cast(fun)->Call(global, 1, argv); + if (try_catch.HasCaught()) return true; v8::String::Utf8Value str(s); fwrite(*str, sizeof(**str), str.length(), stdout); printf("\n"); @@ -905,12 +907,6 @@ Handle Shell::Uint8ClampedArray(const Arguments& args) { } -Handle Shell::Yield(const Arguments& args) { - v8::Unlocker unlocker(args.GetIsolate()); - return Undefined(args.GetIsolate()); -} - - Handle Shell::Quit(const Arguments& args) { int exit_code = args[0]->Int32Value(); OnExit(); diff --git a/deps/v8/src/d8.h b/deps/v8/src/d8.h index 621ac74095..2789c07638 100644 --- a/deps/v8/src/d8.h +++ b/deps/v8/src/d8.h @@ -298,13 +298,8 @@ class Shell : public i::AllStatic { #endif // ENABLE_DEBUGGER_SUPPORT #endif // V8_SHARED -#ifdef WIN32 -#undef Yield -#endif - static Handle Print(const Arguments& args); static Handle Write(const Arguments& args); - static Handle Yield(const Arguments& args); static Handle Quit(const Arguments& args); static Handle Version(const Arguments& args); static Handle EnableProfiler(const Arguments& args); diff --git a/deps/v8/src/d8.js b/deps/v8/src/d8.js index 1ff0ce8980..df1046133f 100644 --- a/deps/v8/src/d8.js +++ b/deps/v8/src/d8.js @@ -2214,7 +2214,8 @@ function Stringify(x, depth) { return x.toString(); case "string": return "\"" + x.toString() + "\""; - // TODO(rossberg): add symbol case + case "symbol": + return "Symbol(" + (x.name ? Stringify(x.name, depth) : "") + ")" case "object": if (x === null) return "null"; if (x.constructor && x.constructor.name === "Array") { diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc index 7a876e71fd..91af9ccc1b 100644 --- a/deps/v8/src/debug.cc +++ b/deps/v8/src/debug.cc @@ -3761,8 +3761,8 @@ void LockingCommandMessageQueue::Clear() { MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) : Thread("v8:MsgDispHelpr"), - sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()), - already_signalled_(false) { + isolate_(isolate), sem_(OS::CreateSemaphore(0)), + mutex_(OS::CreateMutex()), already_signalled_(false) { } @@ -3785,7 +3785,6 @@ void MessageDispatchHelperThread::Schedule() { void MessageDispatchHelperThread::Run() { - Isolate* isolate = Isolate::Current(); while (true) { sem_->Wait(); { @@ -3793,8 +3792,8 @@ void MessageDispatchHelperThread::Run() { already_signalled_ = false; } { - Locker locker(reinterpret_cast(isolate)); - isolate->debugger()->CallMessageDispatchHandler(); + Locker locker(reinterpret_cast(isolate_)); + isolate_->debugger()->CallMessageDispatchHandler(); } } } diff --git a/deps/v8/src/debug.h b/deps/v8/src/debug.h index c7f06815b9..459073fe0c 100644 --- a/deps/v8/src/debug.h +++ b/deps/v8/src/debug.h @@ -1041,6 +1041,7 @@ class MessageDispatchHelperThread: public Thread { private: void Run(); + Isolate* isolate_; Semaphore* const sem_; Mutex* const mutex_; bool already_signalled_; diff --git a/deps/v8/src/deoptimizer.cc b/deps/v8/src/deoptimizer.cc index f03025cbfb..601faf723d 100644 --- a/deps/v8/src/deoptimizer.cc +++ b/deps/v8/src/deoptimizer.cc @@ -1280,29 +1280,37 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } intptr_t caller_arg_count = 0; - if (descriptor->stack_parameter_count_ != NULL) { - caller_arg_count = - input_->GetRegister(descriptor->stack_parameter_count_->code()); - } + bool arg_count_known = descriptor->stack_parameter_count_ == NULL; // Build the Arguments object for the caller's parameters and a pointer to it. output_frame_offset -= kPointerSize; - value = frame_ptr + StandardFrameConstants::kCallerSPOffset + - (caller_arg_count - 1) * kPointerSize; - output_frame->SetFrameSlot(output_frame_offset, value); + int args_arguments_offset = output_frame_offset; + intptr_t the_hole = reinterpret_cast( + isolate_->heap()->the_hole_value()); + if (arg_count_known) { + value = frame_ptr + StandardFrameConstants::kCallerSPOffset + + (caller_arg_count - 1) * kPointerSize; + } else { + value = the_hole; + } + + output_frame->SetFrameSlot(args_arguments_offset, value); if (trace_) { PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; args.arguments\n", - top_address + output_frame_offset, output_frame_offset, value); + V8PRIxPTR " ; args.arguments %s\n", + top_address + args_arguments_offset, args_arguments_offset, value, + arg_count_known ? "" : "(the hole)"); } output_frame_offset -= kPointerSize; - value = caller_arg_count; - output_frame->SetFrameSlot(output_frame_offset, value); + int length_frame_offset = output_frame_offset; + value = arg_count_known ? caller_arg_count : the_hole; + output_frame->SetFrameSlot(length_frame_offset, value); if (trace_) { PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; args.length\n", - top_address + output_frame_offset, output_frame_offset, value); + V8PRIxPTR " ; args.length %s\n", + top_address + length_frame_offset, length_frame_offset, value, + arg_count_known ? "" : "(the hole)"); } output_frame_offset -= kPointerSize; @@ -1321,6 +1329,20 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, DoTranslateCommand(iterator, 0, output_frame_offset); } + if (!arg_count_known) { + DoTranslateCommand(iterator, 0, length_frame_offset, + TRANSLATED_VALUE_IS_NATIVE); + caller_arg_count = output_frame->GetFrameSlot(length_frame_offset); + value = frame_ptr + StandardFrameConstants::kCallerSPOffset + + (caller_arg_count - 1) * kPointerSize; + output_frame->SetFrameSlot(args_arguments_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; args.arguments\n", + top_address + args_arguments_offset, args_arguments_offset, value); + } + } + ASSERT(0 == output_frame_offset); // Copy the double registers from the input into the output frame. @@ -1331,8 +1353,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, // Compute this frame's PC, state, and continuation. Code* trampoline = NULL; - int extra = descriptor->extra_expression_stack_count_; - StubFailureTrampolineStub(extra).FindCodeInCache(&trampoline, isolate_); + StubFunctionMode function_mode = descriptor->function_mode_; + StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline, + isolate_); ASSERT(trampoline != NULL); output_frame->SetPc(reinterpret_cast( trampoline->instruction_start())); @@ -1476,12 +1499,25 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( #endif +static const char* TraceValueType(bool is_smi, bool is_native) { + if (is_native) { + return "native"; + } else if (is_smi) { + return "smi"; + } + + return "heap number"; +} + + void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, - int frame_index, - unsigned output_offset) { + int frame_index, + unsigned output_offset, + DeoptimizerTranslatedValueType value_type) { disasm::NameConverter converter; // A GC-safe temporary placeholder that we can put in the output frame. const intptr_t kPlaceholder = reinterpret_cast(Smi::FromInt(0)); + bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; // Ignore commands marked as duplicate and act on the first non-duplicate. Translation::Opcode opcode = @@ -1524,7 +1560,9 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, case Translation::INT32_REGISTER: { int input_reg = iterator->Next(); intptr_t value = input_->GetRegister(input_reg); - bool is_smi = Smi::IsValid(value); + bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && + Smi::IsValid(value); + if (trace_) { PrintF( " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", @@ -1532,15 +1570,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, converter.NameOfCPURegister(input_reg), - is_smi ? "smi" : "heap number"); + TraceValueType(is_smi, is_native)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); + } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { + output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -1551,7 +1592,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, case Translation::UINT32_REGISTER: { int input_reg = iterator->Next(); uintptr_t value = static_cast(input_->GetRegister(input_reg)); - bool is_smi = (value <= static_cast(Smi::kMaxValue)); + bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && + (value <= static_cast(Smi::kMaxValue)); if (trace_) { PrintF( " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR @@ -1560,15 +1602,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, converter.NameOfCPURegister(input_reg), - is_smi ? "smi" : "heap number"); + TraceValueType(is_smi, is_native)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); + } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { + output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -1617,7 +1662,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); intptr_t value = input_->GetFrameSlot(input_offset); - bool is_smi = Smi::IsValid(value); + bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && + Smi::IsValid(value); if (trace_) { PrintF(" 0x%08" V8PRIxPTR ": ", output_[frame_index]->GetTop() + output_offset); @@ -1625,15 +1671,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, input_offset, - is_smi ? "smi" : "heap number"); + TraceValueType(is_smi, is_native)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); + } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { + output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -1647,7 +1696,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, input_->GetOffsetFromSlotIndex(input_slot_index); uintptr_t value = static_cast(input_->GetFrameSlot(input_offset)); - bool is_smi = (value <= static_cast(Smi::kMaxValue)); + bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && + (value <= static_cast(Smi::kMaxValue)); if (trace_) { PrintF(" 0x%08" V8PRIxPTR ": ", output_[frame_index]->GetTop() + output_offset); @@ -1655,15 +1705,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, input_offset, - is_smi ? "smi" : "heap number"); + TraceValueType(is_smi, is_native)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); + } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { + output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -2130,7 +2183,8 @@ void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, ASSERT(static_cast(Deoptimizer::GetMaxDeoptTableSize()) >= desc.instr_size); chunk->CommitArea(desc.instr_size); - memcpy(chunk->area_start(), desc.buffer, desc.instr_size); + CopyBytes(chunk->area_start(), desc.buffer, + static_cast(desc.instr_size)); CPU::FlushICache(chunk->area_start(), desc.instr_size); if (type == EAGER) { diff --git a/deps/v8/src/deoptimizer.h b/deps/v8/src/deoptimizer.h index db0cc0bdeb..895ed66909 100644 --- a/deps/v8/src/deoptimizer.h +++ b/deps/v8/src/deoptimizer.h @@ -356,9 +356,17 @@ class Deoptimizer : public Malloced { bool is_setter_stub_frame); void DoComputeCompiledStubFrame(TranslationIterator* iterator, int frame_index); + + enum DeoptimizerTranslatedValueType { + TRANSLATED_VALUE_IS_NATIVE, + TRANSLATED_VALUE_IS_TAGGED + }; + void DoTranslateCommand(TranslationIterator* iterator, - int frame_index, - unsigned output_offset); + int frame_index, + unsigned output_offset, + DeoptimizerTranslatedValueType value_type = TRANSLATED_VALUE_IS_TAGGED); + // Translate a command for OSR. Updates the input offset to be used for // the next command. Returns false if translation of the command failed // (e.g., a number conversion failed) and may or may not have updated the diff --git a/deps/v8/src/elements-kind.h b/deps/v8/src/elements-kind.h index cb3bb9c9e9..da151924be 100644 --- a/deps/v8/src/elements-kind.h +++ b/deps/v8/src/elements-kind.h @@ -110,10 +110,15 @@ inline bool IsFastDoubleElementsKind(ElementsKind kind) { } +inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) { + return kind == EXTERNAL_DOUBLE_ELEMENTS || + kind == EXTERNAL_FLOAT_ELEMENTS; +} + + inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { return IsFastDoubleElementsKind(kind) || - kind == EXTERNAL_DOUBLE_ELEMENTS || - kind == EXTERNAL_FLOAT_ELEMENTS; + IsExternalFloatOrDoubleElementsKind(kind); } diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h index c4b560bc8f..ea72168b78 100644 --- a/deps/v8/src/flag-definitions.h +++ b/deps/v8/src/flag-definitions.h @@ -148,6 +148,9 @@ DEFINE_bool(harmony_collections, false, "enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony_observation, false, "enable harmony object observation (implies harmony collections") +DEFINE_bool(harmony_typed_arrays, false, + "enable harmony typed arrays") +DEFINE_bool(harmony_generators, false, "enable harmony generators") DEFINE_bool(harmony, false, "enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) @@ -155,14 +158,18 @@ DEFINE_implication(harmony, harmony_symbols) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony, harmony_observation) +DEFINE_implication(harmony, harmony_generators) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_implication(harmony_observation, harmony_collections) +DEFINE_implication(harmony, harmony_typed_arrays) // Flags for experimental implementation features. DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values") DEFINE_bool(compiled_transitions, false, "use optimizing compiler to " "generate array elements transition stubs") +DEFINE_bool(compiled_keyed_stores, false, "use optimizing compiler to " + "generate keyed store stubs") DEFINE_bool(clever_optimizations, true, "Optimize object size, Array shift, DOM strings and string +") @@ -424,7 +431,7 @@ DEFINE_bool(trace_external_memory, false, "it is adjusted.") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") -DEFINE_bool(weak_embedded_maps_in_optimized_code, true, +DEFINE_bool(weak_embedded_maps_in_optimized_code, false, "make maps embedded in optimized code weak") DEFINE_bool(flush_code, true, "flush code that we expect not to use again (during full gc)") diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc index ed407e796b..aaf8c79e23 100644 --- a/deps/v8/src/frames.cc +++ b/deps/v8/src/frames.cc @@ -1311,18 +1311,19 @@ Address StubFailureTrampolineFrame::GetCallerStackPointer() const { Code* StubFailureTrampolineFrame::unchecked_code() const { - int i = 0; - for (; i <= StubFailureTrampolineStub::kMaxExtraExpressionStackCount; ++i) { - Code* trampoline; - StubFailureTrampolineStub(i).FindCodeInCache(&trampoline, isolate()); - ASSERT(trampoline != NULL); - Address current_pc = pc(); - Address code_start = trampoline->instruction_start(); - Address code_end = code_start + trampoline->instruction_size(); - if (code_start <= current_pc && current_pc < code_end) { - return trampoline; - } + Code* trampoline; + StubFailureTrampolineStub(NOT_JS_FUNCTION_STUB_MODE). + FindCodeInCache(&trampoline, isolate()); + if (trampoline->contains(pc())) { + return trampoline; } + + StubFailureTrampolineStub(JS_FUNCTION_STUB_MODE). + FindCodeInCache(&trampoline, isolate()); + if (trampoline->contains(pc())) { + return trampoline; + } + UNREACHABLE(); return NULL; } diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc index cb6f228a17..1c6a0b91b3 100644 --- a/deps/v8/src/full-codegen.cc +++ b/deps/v8/src/full-codegen.cc @@ -232,6 +232,12 @@ void BreakableStatementChecker::VisitAssignment(Assignment* expr) { } +void BreakableStatementChecker::VisitYield(Yield* expr) { + // Yield is breakable if the expression is. + Visit(expr->expression()); +} + + void BreakableStatementChecker::VisitThrow(Throw* expr) { // Throw is breakable if the expression is. Visit(expr->exception()); @@ -1538,6 +1544,28 @@ void FullCodeGenerator::VisitSharedFunctionInfoLiteral( } +void FullCodeGenerator::VisitYield(Yield* expr) { + if (expr->is_delegating_yield()) + UNIMPLEMENTED(); + + Comment cmnt(masm_, "[ Yield"); + VisitForAccumulatorValue(expr->expression()); + // TODO(wingo): Assert that the operand stack depth is 0, at least while + // general yield expressions are unimplemented. + + // TODO(wingo): What follows is as in VisitReturnStatement. Replace it with a + // call to a builtin that will resume the generator. + NestedStatement* current = nesting_stack_; + int stack_depth = 0; + int context_length = 0; + while (current != NULL) { + current = current->Exit(&stack_depth, &context_length); + } + __ Drop(stack_depth); + EmitReturnSequence(); +} + + void FullCodeGenerator::VisitThrow(Throw* expr) { Comment cmnt(masm_, "[ Throw"); VisitForStackValue(expr->exception()); diff --git a/deps/v8/src/gdb-jit.cc b/deps/v8/src/gdb-jit.cc index dde6bbdaad..cf8ca2d4d9 100644 --- a/deps/v8/src/gdb-jit.cc +++ b/deps/v8/src/gdb-jit.cc @@ -187,7 +187,7 @@ class Writer BASE_EMBEDDED { byte* buffer_; }; -class StringTable; +class ELFStringTable; template class DebugSectionBase : public ZoneObject { @@ -338,7 +338,7 @@ class ELFSection : public DebugSectionBase { virtual ~ELFSection() { } - void PopulateHeader(Writer::Slot
header, StringTable* strtab); + void PopulateHeader(Writer::Slot
header, ELFStringTable* strtab); virtual void WriteBody(Writer::Slot
header, Writer* w) { uintptr_t start = w->position(); @@ -438,9 +438,9 @@ class FullHeaderELFSection : public ELFSection { }; -class StringTable : public ELFSection { +class ELFStringTable : public ELFSection { public: - explicit StringTable(const char* name) + explicit ELFStringTable(const char* name) : ELFSection(name, TYPE_STRTAB, 1), writer_(NULL), offset_(0), size_(0) { } @@ -488,7 +488,7 @@ class StringTable : public ELFSection { void ELFSection::PopulateHeader(Writer::Slot header, - StringTable* strtab) { + ELFStringTable* strtab) { header->name = strtab->Add(name_); header->type = type_; header->alignment = align_; @@ -631,7 +631,7 @@ class ELF BASE_EMBEDDED { public: ELF(Zone* zone) : sections_(6, zone) { sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone); - sections_.Add(new(zone) StringTable(".shstrtab"), zone); + sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone); } void Write(Writer* w) { @@ -718,7 +718,7 @@ class ELF BASE_EMBEDDED { w->CreateSlotsHere(sections_.length()); // String table for section table is the first section. - StringTable* strtab = static_cast(SectionAt(1)); + ELFStringTable* strtab = static_cast(SectionAt(1)); strtab->AttachWriter(w); for (int i = 0, length = sections_.length(); i < length; @@ -832,7 +832,7 @@ class ELFSymbol BASE_EMBEDDED { }; #endif - void Write(Writer::Slot s, StringTable* t) { + void Write(Writer::Slot s, ELFStringTable* t) { // Convert symbol names from strings to indexes in the string table. s->name = t->Add(name); s->value = value; @@ -871,8 +871,8 @@ class ELFSymbolTable : public ELFSection { header->size = w->position() - header->offset; // String table for this symbol table should follow it in the section table. - StringTable* strtab = - static_cast(w->debug_object()->SectionAt(index() + 1)); + ELFStringTable* strtab = + static_cast(w->debug_object()->SectionAt(index() + 1)); strtab->AttachWriter(w); symbols.at(0).set(ELFSymbol::SerializedLayout(0, 0, @@ -905,7 +905,7 @@ class ELFSymbolTable : public ELFSection { private: void WriteSymbolsList(const ZoneList* src, Writer::Slot dst, - StringTable* strtab) { + ELFStringTable* strtab) { for (int i = 0, len = src->length(); i < len; i++) { @@ -1023,7 +1023,7 @@ static void CreateSymbolsTable(CodeDescription* desc, int text_section_index) { Zone* zone = desc->info()->zone(); ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone); - StringTable* strtab = new(zone) StringTable(".strtab"); + ELFStringTable* strtab = new(zone) ELFStringTable(".strtab"); // Symbol table should be followed by the linked string table. elf->AddSection(symtab, zone); @@ -1996,7 +1996,7 @@ static GDBJITLineInfo* UntagLineInfo(void* ptr) { } -void GDBJITInterface::AddCode(Handle name, +void GDBJITInterface::AddCode(Handle name, Handle