Browse Source

V8: Upgrade to 3.18.1

v0.11.2-release
isaacs 12 years ago
parent
commit
50624a50ee
  1. 2
      deps/v8/.gitignore
  2. 9
      deps/v8/ChangeLog
  3. 1612
      deps/v8/SConstruct
  4. 9
      deps/v8/build/common.gypi
  5. 38
      deps/v8/preparser/SConscript
  6. 38
      deps/v8/samples/SConscript
  7. 413
      deps/v8/src/SConscript
  8. 3
      deps/v8/src/api.cc
  9. 21
      deps/v8/src/arguments.h
  10. 25
      deps/v8/src/arm/assembler-arm-inl.h
  11. 4
      deps/v8/src/arm/assembler-arm.cc
  12. 26
      deps/v8/src/arm/assembler-arm.h
  13. 7
      deps/v8/src/arm/code-stubs-arm.cc
  14. 2
      deps/v8/src/arm/code-stubs-arm.h
  15. 37
      deps/v8/src/arm/constants-arm.h
  16. 2
      deps/v8/src/arm/cpu-arm.cc
  17. 20
      deps/v8/src/arm/debug-arm.cc
  18. 12
      deps/v8/src/arm/full-codegen-arm.cc
  19. 10
      deps/v8/src/arm/lithium-arm.cc
  20. 71
      deps/v8/src/arm/lithium-codegen-arm.cc
  21. 4
      deps/v8/src/arm/lithium-codegen-arm.h
  22. 88
      deps/v8/src/arm/macro-assembler-arm.cc
  23. 9
      deps/v8/src/arm/macro-assembler-arm.h
  24. 134
      deps/v8/src/arm/simulator-arm.cc
  25. 6
      deps/v8/src/arm/simulator-arm.h
  26. 2
      deps/v8/src/atomicops_internals_x86_gcc.h
  27. 34
      deps/v8/src/builtins.cc
  28. 2
      deps/v8/src/builtins.h
  29. 23
      deps/v8/src/code-stubs-hydrogen.cc
  30. 6
      deps/v8/src/code-stubs.cc
  31. 30
      deps/v8/src/code-stubs.h
  32. 9
      deps/v8/src/codegen.cc
  33. 10
      deps/v8/src/compiler.cc
  34. 2
      deps/v8/src/compiler.h
  35. 5
      deps/v8/src/deoptimizer.cc
  36. 3
      deps/v8/src/disassembler.cc
  37. 11
      deps/v8/src/factory.cc
  38. 4
      deps/v8/src/factory.h
  39. 20
      deps/v8/src/generator.js
  40. 7
      deps/v8/src/heap-inl.h
  41. 5
      deps/v8/src/heap.cc
  42. 6
      deps/v8/src/heap.h
  43. 45
      deps/v8/src/hydrogen-instructions.cc
  44. 9
      deps/v8/src/hydrogen-instructions.h
  45. 453
      deps/v8/src/hydrogen.cc
  46. 185
      deps/v8/src/hydrogen.h
  47. 1
      deps/v8/src/ia32/code-stubs-ia32.cc
  48. 2
      deps/v8/src/ia32/code-stubs-ia32.h
  49. 12
      deps/v8/src/ia32/full-codegen-ia32.cc
  50. 20
      deps/v8/src/ia32/lithium-codegen-ia32.cc
  51. 5
      deps/v8/src/ia32/lithium-codegen-ia32.h
  52. 12
      deps/v8/src/ia32/lithium-ia32.cc
  53. 4
      deps/v8/src/ic.cc
  54. 6
      deps/v8/src/lithium.cc
  55. 2
      deps/v8/src/lithium.h
  56. 1
      deps/v8/src/log.cc
  57. 1
      deps/v8/src/macros.py
  58. 1
      deps/v8/src/mips/code-stubs-mips.cc
  59. 2
      deps/v8/src/mips/code-stubs-mips.h
  60. 13
      deps/v8/src/mips/full-codegen-mips.cc
  61. 12
      deps/v8/src/mips/lithium-codegen-mips.cc
  62. 7
      deps/v8/src/mips/lithium-codegen-mips.h
  63. 23
      deps/v8/src/objects-inl.h
  64. 2
      deps/v8/src/objects-printer.cc
  65. 3
      deps/v8/src/objects.cc
  66. 23
      deps/v8/src/objects.h
  67. 15
      deps/v8/src/parser.cc
  68. 2
      deps/v8/src/platform-freebsd.cc
  69. 2
      deps/v8/src/platform-linux.cc
  70. 17
      deps/v8/src/platform-posix.cc
  71. 3
      deps/v8/src/runtime-profiler.cc
  72. 38
      deps/v8/src/runtime.cc
  73. 13
      deps/v8/src/runtime.h
  74. 3
      deps/v8/src/safepoint-table.cc
  75. 1
      deps/v8/src/spaces.cc
  76. 2
      deps/v8/src/version.cc
  77. 49
      deps/v8/src/x64/code-stubs-x64.cc
  78. 2
      deps/v8/src/x64/code-stubs-x64.h
  79. 7
      deps/v8/src/x64/frames-x64.h
  80. 12
      deps/v8/src/x64/full-codegen-x64.cc
  81. 19
      deps/v8/src/x64/lithium-codegen-x64.cc
  82. 3
      deps/v8/src/x64/lithium-codegen-x64.h
  83. 12
      deps/v8/src/x64/lithium-x64.cc
  84. 105
      deps/v8/test/benchmarks/testcfg.py
  85. 152
      deps/v8/test/cctest/SConscript
  86. 4
      deps/v8/test/cctest/cctest.gyp
  87. 97
      deps/v8/test/cctest/testcfg.py
  88. 14
      deps/v8/test/es5conform/README
  89. 316
      deps/v8/test/es5conform/es5conform.status
  90. 74
      deps/v8/test/es5conform/harness-adapt.js
  91. 114
      deps/v8/test/es5conform/testcfg.py
  92. 115
      deps/v8/test/message/testcfg.py
  93. 27
      deps/v8/test/mjsunit/harmony/generators-objects.js
  94. 2
      deps/v8/test/mjsunit/harmony/typedarrays.js
  95. 31
      deps/v8/test/mjsunit/regress/regress-grow-store-smi-check.js
  96. 21
      deps/v8/test/mjsunit/string-fromcharcode.js
  97. 133
      deps/v8/test/mjsunit/testcfg.py
  98. 97
      deps/v8/test/mozilla/testcfg.py
  99. 144
      deps/v8/test/preparser/testcfg.py
  100. 6
      deps/v8/test/sputnik/README

2
deps/v8/.gitignore

@ -29,7 +29,6 @@ shell_g
/obj /obj
/out /out
/test/cctest/cctest.status2 /test/cctest/cctest.status2
/test/es5conform/data
/test/message/message.status2 /test/message/message.status2
/test/mjsunit/mjsunit.status2 /test/mjsunit/mjsunit.status2
/test/mozilla/CHECKED_OUT_VERSION /test/mozilla/CHECKED_OUT_VERSION
@ -37,7 +36,6 @@ shell_g
/test/mozilla/downloaded_* /test/mozilla/downloaded_*
/test/mozilla/mozilla.status2 /test/mozilla/mozilla.status2
/test/preparser/preparser.status2 /test/preparser/preparser.status2
/test/sputnik/sputniktests
/test/test262/data /test/test262/data
/test/test262/test262-* /test/test262/test262-*
/test/test262/test262.status2 /test/test262/test262.status2

9
deps/v8/ChangeLog

@ -1,3 +1,12 @@
2013-04-18: Version 3.18.1
Removed SCons related files and deprecated test suite configurations.
Improved handling of unary plus (issue 2527).
Performance and stability improvements on all platforms.
2013-04-17: Version 3.18.0 2013-04-17: Version 3.18.0
Enabled pretenuring of fast literals in high promotion mode. Enabled pretenuring of fast literals in high promotion mode.

1612
deps/v8/SConstruct

File diff suppressed because it is too large

9
deps/v8/build/common.gypi

@ -454,6 +454,15 @@
}], }],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" \ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" \
or OS=="android"', { or OS=="android"', {
'cflags!': [
'-O2',
'-Os',
],
'cflags': [
'-fdata-sections',
'-ffunction-sections',
'-O3',
],
'conditions': [ 'conditions': [
[ 'gcc_version==44 and clang==0', { [ 'gcc_version==44 and clang==0', {
'cflags': [ 'cflags': [

38
deps/v8/preparser/SConscript

@ -1,38 +0,0 @@
# Copyright 2011 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from os.path import join
Import('context tools')
def ConfigureObjectFiles():
env = Environment(tools=tools)
env.Replace(**context.flags['preparser'])
context.ApplyEnvOverrides(env)
return env.Object('preparser-process.cc')
preparser_object = ConfigureObjectFiles()
Return('preparser_object')

38
deps/v8/samples/SConscript

@ -1,38 +0,0 @@
# Copyright 2008 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from os.path import join
Import('sample context tools')
def ConfigureObjectFiles():
env = Environment(tools=tools)
env.Replace(**context.flags['sample'])
context.ApplyEnvOverrides(env)
return env.Object(sample + '.cc')
sample_object = ConfigureObjectFiles()
Return('sample_object')

413
deps/v8/src/SConscript

@ -1,413 +0,0 @@
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import sys
from os.path import join, dirname, abspath
root_dir = dirname(File('SConstruct').rfile().abspath)
sys.path.append(join(root_dir, 'tools'))
import js2c
Import('context')
Import('tools')
Import('d8_env')
SOURCES = {
'all': Split("""
accessors.cc
allocation.cc
api.cc
assembler.cc
ast.cc
atomicops_internals_x86_gcc.cc
bignum-dtoa.cc
bignum.cc
bootstrapper.cc
builtins.cc
cached-powers.cc
checks.cc
circular-queue.cc
code-stubs.cc
codegen.cc
compilation-cache.cc
compiler.cc
contexts.cc
conversions.cc
counters.cc
cpu-profiler.cc
data-flow.cc
date.cc
dateparser.cc
debug-agent.cc
debug.cc
deoptimizer.cc
disassembler.cc
diy-fp.cc
dtoa.cc
elements-kind.cc
elements.cc
execution.cc
extensions/externalize-string-extension.cc
extensions/gc-extension.cc
extensions/statistics-extension.cc
factory.cc
fast-dtoa.cc
fixed-dtoa.cc
flags.cc
frames.cc
full-codegen.cc
func-name-inferrer.cc
gdb-jit.cc
global-handles.cc
handles.cc
heap-profiler.cc
heap-snapshot-generator.cc
heap.cc
hydrogen-instructions.cc
hydrogen.cc
ic.cc
incremental-marking.cc
interface.cc
interpreter-irregexp.cc
isolate.cc
jsregexp.cc
lithium-allocator.cc
lithium.cc
liveedit.cc
log-utils.cc
log.cc
mark-compact.cc
messages.cc
objects-printer.cc
objects-visiting.cc
objects.cc
once.cc
optimizing-compiler-thread.cc
parser.cc
preparse-data.cc
preparser.cc
profile-generator.cc
property.cc
regexp-macro-assembler-irregexp.cc
regexp-macro-assembler.cc
regexp-stack.cc
rewriter.cc
runtime-profiler.cc
runtime.cc
safepoint-table.cc
scanner-character-streams.cc
scanner.cc
scopeinfo.cc
scopes.cc
serialize.cc
snapshot-common.cc
spaces.cc
store-buffer.cc
string-search.cc
string-stream.cc
strtod.cc
stub-cache.cc
token.cc
transitions.cc
type-info.cc
unicode.cc
utils.cc
v8-counters.cc
v8.cc
v8conversions.cc
v8threads.cc
v8utils.cc
variables.cc
version.cc
zone.cc
"""),
'arch:arm': Split("""
arm/builtins-arm.cc
arm/code-stubs-arm.cc
arm/codegen-arm.cc
arm/constants-arm.cc
arm/cpu-arm.cc
arm/debug-arm.cc
arm/deoptimizer-arm.cc
arm/disasm-arm.cc
arm/frames-arm.cc
arm/full-codegen-arm.cc
arm/ic-arm.cc
arm/lithium-arm.cc
arm/lithium-codegen-arm.cc
arm/lithium-gap-resolver-arm.cc
arm/macro-assembler-arm.cc
arm/regexp-macro-assembler-arm.cc
arm/stub-cache-arm.cc
arm/assembler-arm.cc
"""),
'arch:mips': Split("""
mips/assembler-mips.cc
mips/builtins-mips.cc
mips/code-stubs-mips.cc
mips/codegen-mips.cc
mips/constants-mips.cc
mips/cpu-mips.cc
mips/debug-mips.cc
mips/deoptimizer-mips.cc
mips/disasm-mips.cc
mips/frames-mips.cc
mips/full-codegen-mips.cc
mips/ic-mips.cc
mips/lithium-codegen-mips.cc
mips/lithium-gap-resolver-mips.cc
mips/lithium-mips.cc
mips/macro-assembler-mips.cc
mips/regexp-macro-assembler-mips.cc
mips/stub-cache-mips.cc
"""),
'arch:ia32': Split("""
ia32/assembler-ia32.cc
ia32/builtins-ia32.cc
ia32/code-stubs-ia32.cc
ia32/codegen-ia32.cc
ia32/cpu-ia32.cc
ia32/debug-ia32.cc
ia32/deoptimizer-ia32.cc
ia32/disasm-ia32.cc
ia32/frames-ia32.cc
ia32/full-codegen-ia32.cc
ia32/ic-ia32.cc
ia32/lithium-codegen-ia32.cc
ia32/lithium-gap-resolver-ia32.cc
ia32/lithium-ia32.cc
ia32/macro-assembler-ia32.cc
ia32/regexp-macro-assembler-ia32.cc
ia32/stub-cache-ia32.cc
"""),
'arch:x64': Split("""
x64/assembler-x64.cc
x64/builtins-x64.cc
x64/code-stubs-x64.cc
x64/codegen-x64.cc
x64/cpu-x64.cc
x64/debug-x64.cc
x64/deoptimizer-x64.cc
x64/disasm-x64.cc
x64/frames-x64.cc
x64/full-codegen-x64.cc
x64/ic-x64.cc
x64/lithium-codegen-x64.cc
x64/lithium-gap-resolver-x64.cc
x64/lithium-x64.cc
x64/macro-assembler-x64.cc
x64/regexp-macro-assembler-x64.cc
x64/stub-cache-x64.cc
"""),
'simulator:arm': ['arm/simulator-arm.cc'],
'simulator:mips': ['mips/simulator-mips.cc'],
'os:freebsd': ['platform-freebsd.cc', 'platform-posix.cc'],
'os:openbsd': ['platform-openbsd.cc', 'platform-posix.cc'],
'os:linux': ['platform-linux.cc', 'platform-posix.cc'],
'os:android': ['platform-linux.cc', 'platform-posix.cc'],
'os:macos': ['platform-macos.cc', 'platform-posix.cc'],
'os:solaris': ['platform-solaris.cc', 'platform-posix.cc'],
'os:cygwin': ['platform-cygwin.cc', 'platform-posix.cc'],
'os:nullos': ['platform-nullos.cc'],
'os:win32': ['platform-win32.cc', 'win32-math.cc'],
'mode:release': [],
'mode:debug': [
'objects-debug.cc', 'prettyprinter.cc', 'regexp-macro-assembler-tracer.cc'
]
}
PREPARSER_SOURCES = {
'all': Split("""
allocation.cc
bignum.cc
bignum-dtoa.cc
cached-powers.cc
conversions.cc
diy-fp.cc
dtoa.cc
fast-dtoa.cc
fixed-dtoa.cc
preparse-data.cc
preparser.cc
preparser-api.cc
scanner.cc
strtod.cc
token.cc
unicode.cc
utils.cc
"""),
'os:win32': ['win32-math.cc']
}
D8_LIGHT_FILES = {
'all': [
'd8.cc'
]
}
D8_FULL_FILES = {
'all': [
'd8.cc', 'd8-debug.cc'
],
'os:linux': [
'd8-posix.cc'
],
'os:macos': [
'd8-posix.cc'
],
'os:android': [
'd8-posix.cc'
],
'os:freebsd': [
'd8-posix.cc'
],
'os:openbsd': [
'd8-posix.cc'
],
'os:solaris': [
'd8-posix.cc'
],
'os:cygwin': [
'd8-posix.cc'
],
'os:win32': [
'd8-windows.cc'
],
'os:nullos': [
'd8-windows.cc' # Empty implementation at the moment.
],
'console:readline': [
'd8-readline.cc'
]
}
LIBRARY_FILES = '''
runtime.js
v8natives.js
array.js
string.js
uri.js
math.js
messages.js
apinatives.js
date.js
regexp.js
json.js
liveedit-debugger.js
mirror-debugger.js
debug-debugger.js
'''.split()
EXPERIMENTAL_LIBRARY_FILES = '''
symbol.js
proxy.js
collection.js
'''.split()
def Abort(message):
print message
sys.exit(1)
def ConfigureObjectFiles():
env = Environment(tools=tools)
env.Replace(**context.flags['v8'])
context.ApplyEnvOverrides(env)
env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions')
def BuildJS2CEnv(type):
js2c_env = { 'TYPE': type, 'COMPRESSION': 'off' }
if 'COMPRESS_STARTUP_DATA_BZ2' in env['CPPDEFINES']:
js2c_env['COMPRESSION'] = 'bz2'
return js2c_env
# Build the standard platform-independent source files.
source_files = context.GetRelevantSources(SOURCES)
d8_js = env.JS2C('d8-js.cc', 'd8.js', **{'TYPE': 'D8', 'COMPRESSION': 'off'})
d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.'])
if context.options['library'] == 'shared':
d8_files = context.GetRelevantSources(D8_LIGHT_FILES)
d8_objs = []
else:
d8_files = context.GetRelevantSources(D8_FULL_FILES)
d8_objs = [d8_js_obj]
d8_objs.append(context.ConfigureObject(d8_env, [d8_files]))
# Combine the JavaScript library files into a single C++ file and
# compile it.
library_files = [s for s in LIBRARY_FILES]
library_files.append('macros.py')
libraries_src = env.JS2C(
['libraries.cc'], library_files, **BuildJS2CEnv('CORE'))
libraries_obj = context.ConfigureObject(env, libraries_src, CPPPATH=['.'])
# Combine the experimental JavaScript library files into a C++ file
# and compile it.
experimental_library_files = [ s for s in EXPERIMENTAL_LIBRARY_FILES ]
experimental_library_files.append('macros.py')
experimental_libraries_src = env.JS2C(['experimental-libraries.cc'],
experimental_library_files,
**BuildJS2CEnv('EXPERIMENTAL'))
experimental_libraries_obj = context.ConfigureObject(env, experimental_libraries_src, CPPPATH=['.'])
source_objs = context.ConfigureObject(env, source_files)
non_snapshot_files = [source_objs]
preparser_source_files = context.GetRelevantSources(PREPARSER_SOURCES)
preparser_objs = context.ConfigureObject(env, preparser_source_files)
# Create snapshot if necessary. For cross compilation you should either
# do without snapshots and take the performance hit or you should build a
# host VM with the simulator=arm and snapshot=on options and then take the
# resulting snapshot.cc file from obj/release and put it in the src
# directory. Then rebuild the VM with the cross compiler and specify
# snapshot=nobuild on the scons command line.
empty_snapshot_obj = context.ConfigureObject(env, 'snapshot-empty.cc')
mksnapshot_env = env.Copy()
mksnapshot_env.Replace(**context.flags['mksnapshot'])
mksnapshot_src = 'mksnapshot.cc'
mksnapshot = mksnapshot_env.Program('mksnapshot', [mksnapshot_src, libraries_obj, experimental_libraries_obj, non_snapshot_files, empty_snapshot_obj], PDB='mksnapshot.exe.pdb')
if context.use_snapshot:
if context.build_snapshot:
snapshot_cc = env.Snapshot('snapshot.cc', mksnapshot, LOGFILE=File('snapshot.log').abspath)
else:
snapshot_cc = 'snapshot.cc'
snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.'])
else:
snapshot_obj = empty_snapshot_obj
library_objs = [non_snapshot_files, libraries_obj, experimental_libraries_obj, snapshot_obj]
return (library_objs, d8_objs, [mksnapshot], preparser_objs)
(library_objs, d8_objs, mksnapshot, preparser_objs) = ConfigureObjectFiles()
Return('library_objs d8_objs mksnapshot preparser_objs')

3
deps/v8/src/api.cc

@ -623,6 +623,9 @@ i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL; if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
LOG_API(isolate, "Persistent::New"); LOG_API(isolate, "Persistent::New");
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj); i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
#ifdef DEBUG
(*obj)->Verify();
#endif // DEBUG
return result.location(); return result.location();
} }

21
deps/v8/src/arguments.h

@ -115,18 +115,15 @@ class CustomArguments : public Relocatable {
#define DECLARE_RUNTIME_FUNCTION(Type, Name) \ #define DECLARE_RUNTIME_FUNCTION(Type, Name) \
Type Name(int args_length, Object** args_object, Isolate* isolate) Type Name(Arguments args, Isolate* isolate)
#define RUNTIME_FUNCTION(Type, Name) \
static Type __RT_impl_##Name(Arguments args, Isolate* isolate); \ #define RUNTIME_FUNCTION(Type, Name) \
Type Name(int args_length, Object** args_object, Isolate* isolate) { \ Type Name(Arguments args, Isolate* isolate)
Arguments args(args_length, args_object); \
return __RT_impl_##Name(args, isolate); \
} \ #define RUNTIME_ARGUMENTS(isolate, args) args, isolate
static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
#define RUNTIME_ARGUMENTS(isolate, args) \
args.length(), args.arguments(), isolate
} } // namespace v8::internal } } // namespace v8::internal

25
deps/v8/src/arm/assembler-arm-inl.h

@ -266,19 +266,11 @@ Object** RelocInfo::call_object_address() {
bool RelocInfo::IsPatchedReturnSequence() { bool RelocInfo::IsPatchedReturnSequence() {
Instr current_instr = Assembler::instr_at(pc_); Instr current_instr = Assembler::instr_at(pc_);
Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize); Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize);
#ifdef USE_BLX
// A patched return sequence is: // A patched return sequence is:
// ldr ip, [pc, #0] // ldr ip, [pc, #0]
// blx ip // blx ip
return ((current_instr & kLdrPCMask) == kLdrPCPattern) return ((current_instr & kLdrPCMask) == kLdrPCPattern)
&& ((next_instr & kBlxRegMask) == kBlxRegPattern); && ((next_instr & kBlxRegMask) == kBlxRegPattern);
#else
// A patched return sequence is:
// mov lr, pc
// ldr pc, [pc, #-4]
return (current_instr == kMovLrPc)
&& ((next_instr & kLdrPCMask) == kLdrPCPattern);
#endif
} }
@ -408,14 +400,11 @@ Address Assembler::target_pointer_address_at(Address pc) {
instr = Memory::int32_at(target_pc); instr = Memory::int32_at(target_pc);
} }
#ifdef USE_BLX // With a blx instruction, the instruction before is what needs to be patched.
// If we have a blx instruction, the instruction before it is
// what needs to be patched.
if ((instr & kBlxRegMask) == kBlxRegPattern) { if ((instr & kBlxRegMask) == kBlxRegPattern) {
target_pc -= kInstrSize; target_pc -= kInstrSize;
instr = Memory::int32_at(target_pc); instr = Memory::int32_at(target_pc);
} }
#endif
ASSERT(IsLdrPcImmediateOffset(instr)); ASSERT(IsLdrPcImmediateOffset(instr));
int offset = instr & 0xfff; // offset_12 is unsigned int offset = instr & 0xfff; // offset_12 is unsigned
@ -442,7 +431,6 @@ Address Assembler::target_pointer_at(Address pc) {
Address Assembler::target_address_from_return_address(Address pc) { Address Assembler::target_address_from_return_address(Address pc) {
// Returns the address of the call target from the return address that will // Returns the address of the call target from the return address that will
// be returned to after a call. // be returned to after a call.
#ifdef USE_BLX
// Call sequence on V7 or later is : // Call sequence on V7 or later is :
// movw ip, #... @ call address low 16 // movw ip, #... @ call address low 16
// movt ip, #... @ call address high 16 // movt ip, #... @ call address high 16
@ -461,18 +449,10 @@ Address Assembler::target_address_from_return_address(Address pc) {
ASSERT(IsMovW(Memory::int32_at(candidate)) && ASSERT(IsMovW(Memory::int32_at(candidate)) &&
IsMovT(Memory::int32_at(candidate + kInstrSize))); IsMovT(Memory::int32_at(candidate + kInstrSize)));
return candidate; return candidate;
#else
// Call sequence is:
// mov lr, pc
// ldr pc, [pc, #...] @ call address
// @ return address
return pc - kInstrSize;
#endif
} }
Address Assembler::return_address_from_call_start(Address pc) { Address Assembler::return_address_from_call_start(Address pc) {
#ifdef USE_BLX
if (IsLdrPcImmediateOffset(Memory::int32_at(pc))) { if (IsLdrPcImmediateOffset(Memory::int32_at(pc))) {
return pc + kInstrSize * 2; return pc + kInstrSize * 2;
} else { } else {
@ -480,9 +460,6 @@ Address Assembler::return_address_from_call_start(Address pc) {
ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
return pc + kInstrSize * 3; return pc + kInstrSize * 3;
} }
#else
return pc + kInstrSize;
#endif
} }

4
deps/v8/src/arm/assembler-arm.cc

@ -1683,7 +1683,6 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) {
emit(reinterpret_cast<Instr>(msg)); emit(reinterpret_cast<Instr>(msg));
} }
#else // def __arm__ #else // def __arm__
#ifdef CAN_USE_ARMV5_INSTRUCTIONS
if (cond != al) { if (cond != al) {
Label skip; Label skip;
b(&skip, NegateCondition(cond)); b(&skip, NegateCondition(cond));
@ -1692,9 +1691,6 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) {
} else { } else {
bkpt(0); bkpt(0);
} }
#else // ndef CAN_USE_ARMV5_INSTRUCTIONS
svc(0x9f0001, cond);
#endif // ndef CAN_USE_ARMV5_INSTRUCTIONS
#endif // def __arm__ #endif // def __arm__
} }

26
deps/v8/src/arm/assembler-arm.h

@ -663,37 +663,19 @@ class Assembler : public AssemblerBase {
// Distance between start of patched return sequence and the emitted address // Distance between start of patched return sequence and the emitted address
// to jump to. // to jump to.
#ifdef USE_BLX
// Patched return sequence is: // Patched return sequence is:
// ldr ip, [pc, #0] @ emited address and start // ldr ip, [pc, #0] @ emited address and start
// blx ip // blx ip
static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize; static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize;
#else
// Patched return sequence is:
// mov lr, pc @ start of sequence
// ldr pc, [pc, #-4] @ emited address
static const int kPatchReturnSequenceAddressOffset = kInstrSize;
#endif
// Distance between start of patched debug break slot and the emitted address // Distance between start of patched debug break slot and the emitted address
// to jump to. // to jump to.
#ifdef USE_BLX
// Patched debug break slot code is: // Patched debug break slot code is:
// ldr ip, [pc, #0] @ emited address and start // ldr ip, [pc, #0] @ emited address and start
// blx ip // blx ip
static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize;
#else
// Patched debug break slot code is:
// mov lr, pc @ start of sequence
// ldr pc, [pc, #-4] @ emited address
static const int kPatchDebugBreakSlotAddressOffset = kInstrSize;
#endif
#ifdef USE_BLX
static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize; static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
#else
static const int kPatchDebugBreakSlotReturnOffset = kInstrSize;
#endif
// Difference between address of current opcode and value read from pc // Difference between address of current opcode and value read from pc
// register. // register.
@ -1130,16 +1112,8 @@ class Assembler : public AssemblerBase {
static bool use_immediate_embedded_pointer_loads( static bool use_immediate_embedded_pointer_loads(
const Assembler* assembler) { const Assembler* assembler) {
#ifdef USE_BLX
return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) && return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
(assembler == NULL || !assembler->predictable_code_size()); (assembler == NULL || !assembler->predictable_code_size());
#else
// If not using BLX, all loads from the constant pool cannot be immediate,
// because the ldr pc, [pc + #xxxx] used for calls must be a single
// instruction and cannot be easily distinguished out of context from
// other loads that could use movw/movt.
return false;
#endif
} }
// Check the code size generated from label to here. // Check the code size generated from label to here.

7
deps/v8/src/arm/code-stubs-arm.cc

@ -30,7 +30,6 @@
#if defined(V8_TARGET_ARCH_ARM) #if defined(V8_TARGET_ARCH_ARM)
#include "bootstrapper.h" #include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h" #include "code-stubs.h"
#include "regexp-macro-assembler.h" #include "regexp-macro-assembler.h"
#include "stub-cache.h" #include "stub-cache.h"
@ -482,9 +481,7 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
__ Ret(); __ Ret();
__ bind(&not_special); __ bind(&not_special);
// Count leading zeros. Uses mantissa for a scratch register on pre-ARM5. __ clz(zeros_, source_);
// Gets the wrong answer for 0, but we already checked for that case above.
__ CountLeadingZeros(zeros_, source_, mantissa);
// Compute exponent and or it into the exponent register. // Compute exponent and or it into the exponent register.
// We use mantissa as a scratch register here. Use a fudge factor to // We use mantissa as a scratch register here. Use a fudge factor to
// divide the constant 31 + HeapNumber::kExponentBias, 0x41d, into two parts // divide the constant 31 + HeapNumber::kExponentBias, 0x41d, into two parts
@ -2032,7 +2029,7 @@ void BinaryOpStub_GenerateSmiSmiOperation(MacroAssembler* masm,
} }
// Perform division by shifting. // Perform division by shifting.
__ CountLeadingZeros(scratch1, scratch1, scratch2); __ clz(scratch1, scratch1);
__ rsb(scratch1, scratch1, Operand(31)); __ rsb(scratch1, scratch1, Operand(31));
__ mov(right, Operand(left, LSR, scratch1)); __ mov(right, Operand(left, LSR, scratch1));
__ Ret(); __ Ret();

2
deps/v8/src/arm/code-stubs-arm.h

@ -130,7 +130,7 @@ class UnaryOpStub: public PlatformCodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::UNARY_OP_IC; } virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() { virtual InlineCacheState GetICState() {
return UnaryOpIC::ToState(operand_type_); return UnaryOpIC::ToState(operand_type_);

37
deps/v8/src/arm/constants-arm.h

@ -33,13 +33,6 @@
#error ARM EABI support is required. #error ARM EABI support is required.
#endif #endif
// This means that interwork-compatible jump instructions are generated. We
// want to generate them on the simulator too so it makes snapshots that can
// be used on real hardware.
#if defined(__THUMB_INTERWORK__) || !defined(__arm__)
# define USE_THUMB_INTERWORK 1
#endif
#if defined(__ARM_ARCH_7A__) || \ #if defined(__ARM_ARCH_7A__) || \
defined(__ARM_ARCH_7R__) || \ defined(__ARM_ARCH_7R__) || \
defined(__ARM_ARCH_7__) defined(__ARM_ARCH_7__)
@ -49,39 +42,11 @@
#endif #endif
#endif #endif
#if defined(__ARM_ARCH_6__) || \ // Simulator should support unaligned access by default.
defined(__ARM_ARCH_6J__) || \
defined(__ARM_ARCH_6K__) || \
defined(__ARM_ARCH_6Z__) || \
defined(__ARM_ARCH_6ZK__) || \
defined(__ARM_ARCH_6T2__) || \
defined(CAN_USE_ARMV7_INSTRUCTIONS)
# define CAN_USE_ARMV6_INSTRUCTIONS 1
#endif
#if defined(__ARM_ARCH_5__) || \
defined(__ARM_ARCH_5T__) || \
defined(__ARM_ARCH_5TE__) || \
defined(__ARM_ARCH_5TEJ__) || \
defined(CAN_USE_ARMV6_INSTRUCTIONS)
# define CAN_USE_ARMV5_INSTRUCTIONS 1
# define CAN_USE_THUMB_INSTRUCTIONS 1
#endif
// Simulator should support ARM5 instructions and unaligned access by default.
#if !defined(__arm__) #if !defined(__arm__)
# define CAN_USE_ARMV5_INSTRUCTIONS 1
# define CAN_USE_THUMB_INSTRUCTIONS 1
# ifndef CAN_USE_UNALIGNED_ACCESSES # ifndef CAN_USE_UNALIGNED_ACCESSES
# define CAN_USE_UNALIGNED_ACCESSES 1 # define CAN_USE_UNALIGNED_ACCESSES 1
# endif # endif
#endif
// Using blx may yield better code, so use it when required or when available
#if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS)
#define USE_BLX 1
#endif #endif
namespace v8 { namespace v8 {

2
deps/v8/src/arm/cpu-arm.cc

@ -108,7 +108,7 @@ void CPU::FlushICache(void* start, size_t size) {
void CPU::DebugBreak() { void CPU::DebugBreak() {
#if !defined (__arm__) || !defined(CAN_USE_ARMV5_INSTRUCTIONS) #if !defined (__arm__)
UNIMPLEMENTED(); // when building ARM emulator target UNIMPLEMENTED(); // when building ARM emulator target
#else #else
asm volatile("bkpt 0"); asm volatile("bkpt 0");

20
deps/v8/src/arm/debug-arm.cc

@ -48,23 +48,13 @@ void BreakLocationIterator::SetDebugBreakAtReturn() {
// add sp, sp, #4 // add sp, sp, #4
// bx lr // bx lr
// to a call to the debug break return code. // to a call to the debug break return code.
// #ifdef USE_BLX
// ldr ip, [pc, #0] // ldr ip, [pc, #0]
// blx ip // blx ip
// #else
// mov lr, pc
// ldr pc, [pc, #-4]
// #endif
// <debug break return code entry point address> // <debug break return code entry point address>
// bktp 0 // bktp 0
CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions); CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
#ifdef USE_BLX
patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0));
patcher.masm()->blx(v8::internal::ip); patcher.masm()->blx(v8::internal::ip);
#else
patcher.masm()->mov(v8::internal::lr, v8::internal::pc);
patcher.masm()->ldr(v8::internal::pc, MemOperand(v8::internal::pc, -4));
#endif
patcher.Emit(Isolate::Current()->debug()->debug_break_return()->entry()); patcher.Emit(Isolate::Current()->debug()->debug_break_return()->entry());
patcher.masm()->bkpt(0); patcher.masm()->bkpt(0);
} }
@ -99,22 +89,12 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
// mov r2, r2 // mov r2, r2
// mov r2, r2 // mov r2, r2
// to a call to the debug break slot code. // to a call to the debug break slot code.
// #ifdef USE_BLX
// ldr ip, [pc, #0] // ldr ip, [pc, #0]
// blx ip // blx ip
// #else
// mov lr, pc
// ldr pc, [pc, #-4]
// #endif
// <debug break slot code entry point address> // <debug break slot code entry point address>
CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
#ifdef USE_BLX
patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0));
patcher.masm()->blx(v8::internal::ip); patcher.masm()->blx(v8::internal::ip);
#else
patcher.masm()->mov(v8::internal::lr, v8::internal::pc);
patcher.masm()->ldr(v8::internal::pc, MemOperand(v8::internal::pc, -4));
#endif
patcher.Emit(Isolate::Current()->debug()->debug_break_slot()->entry()); patcher.Emit(Isolate::Current()->debug()->debug_break_slot()->entry());
} }

12
deps/v8/src/arm/full-codegen-arm.cc

@ -3976,18 +3976,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
case Token::ADD: {
Comment cmt(masm_, "[ UnaryOperation (ADD)");
VisitForAccumulatorValue(expr->expression());
Label no_conversion;
__ JumpIfSmi(result_register(), &no_conversion);
ToNumberStub convert_stub;
__ CallStub(&convert_stub);
__ bind(&no_conversion);
context()->Plug(result_register());
break;
}
case Token::SUB: case Token::SUB:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break; break;

10
deps/v8/src/arm/lithium-arm.cc

@ -823,11 +823,15 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
HEnvironment* last_environment = pred->last_environment(); HEnvironment* last_environment = pred->last_environment();
for (int i = 0; i < block->phis()->length(); ++i) { for (int i = 0; i < block->phis()->length(); ++i) {
HPhi* phi = block->phis()->at(i); HPhi* phi = block->phis()->at(i);
last_environment->SetValueAt(phi->merged_index(), phi); if (phi->merged_index() < last_environment->length()) {
last_environment->SetValueAt(phi->merged_index(), phi);
}
} }
for (int i = 0; i < block->deleted_phis()->length(); ++i) { for (int i = 0; i < block->deleted_phis()->length(); ++i) {
last_environment->SetValueAt(block->deleted_phis()->at(i), if (block->deleted_phis()->at(i) < last_environment->length()) {
graph_->GetConstantUndefined()); last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
} }
block->UpdateEnvironment(last_environment); block->UpdateEnvironment(last_environment);
// Pick up the outgoing argument count of one of the predecessors. // Pick up the outgoing argument count of one of the predecessors.

71
deps/v8/src/arm/lithium-codegen-arm.cc

@ -304,7 +304,7 @@ bool LCodeGen::GenerateDeferredCode() {
LDeferredCode* code = deferred_[i]; LDeferredCode* code = deferred_[i];
__ bind(code->entry()); __ bind(code->entry());
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred build frame", Comment(";;; Deferred build frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(!frame_is_built_); ASSERT(!frame_is_built_);
@ -320,7 +320,7 @@ bool LCodeGen::GenerateDeferredCode() {
code->instr()->Mnemonic()); code->instr()->Mnemonic());
code->Generate(); code->Generate();
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred destroy frame", Comment(";;; Deferred destroy frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(frame_is_built_); ASSERT(frame_is_built_);
@ -1043,11 +1043,9 @@ void LCodeGen::RecordPosition(int position) {
void LCodeGen::DoLabel(LLabel* label) { void LCodeGen::DoLabel(LLabel* label) {
if (label->is_loop_header()) { Comment(";;; -------------------- B%d%s --------------------",
Comment(";;; B%d - LOOP entry", label->block_id()); label->block_id(),
} else { label->is_loop_header() ? " (loop header)" : "");
Comment(";;; B%d", label->block_id());
}
__ bind(label->label()); __ bind(label->label());
current_block_ = label->block_id(); current_block_ = label->block_id();
DoGap(label); DoGap(label);
@ -2055,33 +2053,38 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
LOperand* left = instr->left(); LOperand* left = instr->left();
LOperand* right = instr->right(); LOperand* right = instr->right();
HMathMinMax::Operation operation = instr->hydrogen()->operation(); HMathMinMax::Operation operation = instr->hydrogen()->operation();
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
if (instr->hydrogen()->representation().IsInteger32()) { if (instr->hydrogen()->representation().IsInteger32()) {
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
Register left_reg = ToRegister(left); Register left_reg = ToRegister(left);
Operand right_op = (right->IsRegister() || right->IsConstantOperand()) Operand right_op = (right->IsRegister() || right->IsConstantOperand())
? ToOperand(right) ? ToOperand(right)
: Operand(EmitLoadRegister(right, ip)); : Operand(EmitLoadRegister(right, ip));
Register result_reg = ToRegister(instr->result()); Register result_reg = ToRegister(instr->result());
__ cmp(left_reg, right_op); __ cmp(left_reg, right_op);
if (!result_reg.is(left_reg)) { __ Move(result_reg, left_reg, condition);
__ mov(result_reg, left_reg, LeaveCC, condition);
}
__ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
} else { } else {
ASSERT(instr->hydrogen()->representation().IsDouble()); ASSERT(instr->hydrogen()->representation().IsDouble());
DwVfpRegister left_reg = ToDoubleRegister(left); DwVfpRegister left_reg = ToDoubleRegister(left);
DwVfpRegister right_reg = ToDoubleRegister(right); DwVfpRegister right_reg = ToDoubleRegister(right);
DwVfpRegister result_reg = ToDoubleRegister(instr->result()); DwVfpRegister result_reg = ToDoubleRegister(instr->result());
Label check_nan_left, check_zero, return_left, return_right, done; Label result_is_nan, return_left, return_right, check_zero, done;
__ VFPCompareAndSetFlags(left_reg, right_reg); __ VFPCompareAndSetFlags(left_reg, right_reg);
__ b(vs, &check_nan_left); if (operation == HMathMinMax::kMathMin) {
__ b(eq, &check_zero); __ b(mi, &return_left);
__ b(condition, &return_left); __ b(gt, &return_right);
__ b(al, &return_right); } else {
__ b(mi, &return_right);
__ bind(&check_zero); __ b(gt, &return_left);
}
__ b(vs, &result_is_nan);
// Left equals right => check for -0.
__ VFPCompareAndSetFlags(left_reg, 0.0); __ VFPCompareAndSetFlags(left_reg, 0.0);
__ b(ne, &return_left); // left == right != 0. if (left_reg.is(result_reg) || right_reg.is(result_reg)) {
__ b(ne, &done); // left == right != 0.
} else {
__ b(ne, &return_left); // left == right != 0.
}
// At this point, both left and right are either 0 or -0. // At this point, both left and right are either 0 or -0.
if (operation == HMathMinMax::kMathMin) { if (operation == HMathMinMax::kMathMin) {
// We could use a single 'vorr' instruction here if we had NEON support. // We could use a single 'vorr' instruction here if we had NEON support.
@ -2093,21 +2096,21 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
// the decision for vadd is easy because vand is a NEON instruction. // the decision for vadd is easy because vand is a NEON instruction.
__ vadd(result_reg, left_reg, right_reg); __ vadd(result_reg, left_reg, right_reg);
} }
__ b(al, &done); __ b(&done);
__ bind(&result_is_nan);
__ vadd(result_reg, left_reg, right_reg);
__ b(&done);
__ bind(&check_nan_left);
__ VFPCompareAndSetFlags(left_reg, left_reg);
__ b(vs, &return_left); // left == NaN.
__ bind(&return_right); __ bind(&return_right);
if (!right_reg.is(result_reg)) { __ Move(result_reg, right_reg);
__ vmov(result_reg, right_reg); if (!left_reg.is(result_reg)) {
__ b(&done);
} }
__ b(al, &done);
__ bind(&return_left); __ bind(&return_left);
if (!left_reg.is(result_reg)) { __ Move(result_reg, left_reg);
__ vmov(result_reg, left_reg);
}
__ bind(&done); __ bind(&done);
} }
} }
@ -2205,12 +2208,10 @@ void LCodeGen::DoBranch(LBranch* instr) {
EmitBranch(true_block, false_block, ne); EmitBranch(true_block, false_block, ne);
} else if (r.IsDouble()) { } else if (r.IsDouble()) {
DwVfpRegister reg = ToDoubleRegister(instr->value()); DwVfpRegister reg = ToDoubleRegister(instr->value());
Register scratch = scratch0();
// Test the double value. Zero and NaN are false. // Test the double value. Zero and NaN are false.
__ VFPCompareAndLoadFlags(reg, 0.0, scratch); __ VFPCompareAndSetFlags(reg, 0.0);
__ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); __ cmp(r0, r0, vs); // If NaN, set the Z flag.
EmitBranch(true_block, false_block, eq); EmitBranch(true_block, false_block, ne);
} else { } else {
ASSERT(r.IsTagged()); ASSERT(r.IsTagged());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
@ -2302,7 +2303,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ b(ne, &not_heap_number); __ b(ne, &not_heap_number);
__ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
__ VFPCompareAndSetFlags(dbl_scratch, 0.0); __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
__ b(vs, false_label); // NaN -> false. __ cmp(r0, r0, vs); // NaN -> false.
__ b(eq, false_label); // +0, -0 -> false. __ b(eq, false_label); // +0, -0 -> false.
__ b(true_label); __ b(true_label);
__ bind(&not_heap_number); __ bind(&not_heap_number);

4
deps/v8/src/arm/lithium-codegen-arm.h

@ -29,10 +29,12 @@
#define V8_ARM_LITHIUM_CODEGEN_ARM_H_ #define V8_ARM_LITHIUM_CODEGEN_ARM_H_
#include "arm/lithium-arm.h" #include "arm/lithium-arm.h"
#include "arm/lithium-gap-resolver-arm.h" #include "arm/lithium-gap-resolver-arm.h"
#include "deoptimizer.h" #include "deoptimizer.h"
#include "safepoint-table.h" #include "safepoint-table.h"
#include "scopes.h" #include "scopes.h"
#include "v8utils.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -211,7 +213,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); } int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
void Abort(const char* reason); void Abort(const char* reason);
void Comment(const char* format, ...); void FPRINTF_CHECKING Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }

88
deps/v8/src/arm/macro-assembler-arm.cc

@ -51,44 +51,15 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
} }
// We always generate arm code, never thumb code, even if V8 is compiled to
// thumb, so we require inter-working support
#if defined(__thumb__) && !defined(USE_THUMB_INTERWORK)
#error "flag -mthumb-interwork missing"
#endif
// We do not support thumb inter-working with an arm architecture not supporting
// the blx instruction (below v5t). If you know what CPU you are compiling for
// you can use -march=armv7 or similar.
#if defined(USE_THUMB_INTERWORK) && !defined(CAN_USE_THUMB_INSTRUCTIONS)
# error "For thumb inter-working we require an architecture which supports blx"
#endif
// Using bx does not yield better code, so use it only when required
#if defined(USE_THUMB_INTERWORK)
#define USE_BX 1
#endif
void MacroAssembler::Jump(Register target, Condition cond) { void MacroAssembler::Jump(Register target, Condition cond) {
#if USE_BX
bx(target, cond); bx(target, cond);
#else
mov(pc, Operand(target), LeaveCC, cond);
#endif
} }
void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode, void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode,
Condition cond) { Condition cond) {
#if USE_BX
mov(ip, Operand(target, rmode)); mov(ip, Operand(target, rmode));
bx(ip, cond); bx(ip, cond);
#else
mov(pc, Operand(target, rmode), LeaveCC, cond);
#endif
} }
@ -108,11 +79,7 @@ void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
int MacroAssembler::CallSize(Register target, Condition cond) { int MacroAssembler::CallSize(Register target, Condition cond) {
#ifdef USE_BLX
return kInstrSize; return kInstrSize;
#else
return 2 * kInstrSize;
#endif
} }
@ -121,13 +88,7 @@ void MacroAssembler::Call(Register target, Condition cond) {
BlockConstPoolScope block_const_pool(this); BlockConstPoolScope block_const_pool(this);
Label start; Label start;
bind(&start); bind(&start);
#ifdef USE_BLX
blx(target, cond); blx(target, cond);
#else
// set lr for return at current pc + 8
mov(lr, Operand(pc), LeaveCC, cond);
mov(pc, Operand(target), LeaveCC, cond);
#endif
ASSERT_EQ(CallSize(target, cond), SizeOfCodeGeneratedSince(&start)); ASSERT_EQ(CallSize(target, cond), SizeOfCodeGeneratedSince(&start));
} }
@ -170,7 +131,6 @@ void MacroAssembler::Call(Address target,
set_predictable_code_size(true); set_predictable_code_size(true);
} }
#ifdef USE_BLX
// Call sequence on V7 or later may be : // Call sequence on V7 or later may be :
// movw ip, #... @ call address low 16 // movw ip, #... @ call address low 16
// movt ip, #... @ call address high 16 // movt ip, #... @ call address high 16
@ -191,12 +151,6 @@ void MacroAssembler::Call(Address target,
mov(ip, Operand(reinterpret_cast<int32_t>(target), rmode)); mov(ip, Operand(reinterpret_cast<int32_t>(target), rmode));
blx(ip, cond); blx(ip, cond);
#else
// Set lr for return at current pc + 8.
mov(lr, Operand(pc), LeaveCC, cond);
// Emit a ldr<cond> pc, [pc + offset of target in constant pool].
mov(pc, Operand(reinterpret_cast<int32_t>(target), rmode), LeaveCC, cond);
#endif
ASSERT_EQ(CallSize(target, rmode, cond), SizeOfCodeGeneratedSince(&start)); ASSERT_EQ(CallSize(target, rmode, cond), SizeOfCodeGeneratedSince(&start));
if (mode == NEVER_INLINE_TARGET_ADDRESS) { if (mode == NEVER_INLINE_TARGET_ADDRESS) {
set_predictable_code_size(old_predictable_code_size); set_predictable_code_size(old_predictable_code_size);
@ -230,11 +184,7 @@ void MacroAssembler::Call(Handle<Code> code,
void MacroAssembler::Ret(Condition cond) { void MacroAssembler::Ret(Condition cond) {
#if USE_BX
bx(lr, cond); bx(lr, cond);
#else
mov(pc, Operand(lr), LeaveCC, cond);
#endif
} }
@ -3226,44 +3176,6 @@ void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
} }
void MacroAssembler::CountLeadingZeros(Register zeros, // Answer.
Register source, // Input.
Register scratch) {
ASSERT(!zeros.is(source) || !source.is(scratch));
ASSERT(!zeros.is(scratch));
ASSERT(!scratch.is(ip));
ASSERT(!source.is(ip));
ASSERT(!zeros.is(ip));
#ifdef CAN_USE_ARMV5_INSTRUCTIONS
clz(zeros, source); // This instruction is only supported after ARM5.
#else
// Order of the next two lines is important: zeros register
// can be the same as source register.
Move(scratch, source);
mov(zeros, Operand::Zero());
// Top 16.
tst(scratch, Operand(0xffff0000));
add(zeros, zeros, Operand(16), LeaveCC, eq);
mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq);
// Top 8.
tst(scratch, Operand(0xff000000));
add(zeros, zeros, Operand(8), LeaveCC, eq);
mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq);
// Top 4.
tst(scratch, Operand(0xf0000000));
add(zeros, zeros, Operand(4), LeaveCC, eq);
mov(scratch, Operand(scratch, LSL, 4), LeaveCC, eq);
// Top 2.
tst(scratch, Operand(0xc0000000));
add(zeros, zeros, Operand(2), LeaveCC, eq);
mov(scratch, Operand(scratch, LSL, 2), LeaveCC, eq);
// Top bit.
tst(scratch, Operand(0x80000000u));
add(zeros, zeros, Operand(1), LeaveCC, eq);
#endif
}
void MacroAssembler::CheckFor32DRegs(Register scratch) { void MacroAssembler::CheckFor32DRegs(Register scratch) {
mov(scratch, Operand(ExternalReference::cpu_features())); mov(scratch, Operand(ExternalReference::cpu_features()));
ldr(scratch, MemOperand(scratch)); ldr(scratch, MemOperand(scratch));

9
deps/v8/src/arm/macro-assembler-arm.h

@ -993,15 +993,6 @@ class MacroAssembler: public Assembler {
Register input_high, Register input_high,
Register input_low); Register input_low);
// Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz
// instruction. On pre-ARM5 hardware this routine gives the wrong answer
// for 0 (31 instead of 32). Source and scratch can be the same in which case
// the source is clobbered. Source and zeros can also be the same in which
// case scratch should be a different register.
void CountLeadingZeros(Register zeros,
Register source,
Register scratch);
// Check whether d16-d31 are available on the CPU. The result is given by the // Check whether d16-d31 are available on the CPU. The result is given by the
// Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise. // Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise.
void CheckFor32DRegs(Register scratch); void CheckFor32DRegs(Register scratch);

134
deps/v8/src/arm/simulator-arm.cc

@ -975,14 +975,12 @@ ReturnType Simulator::GetFromVFPRegister(int reg_index) {
} }
// Runtime FP routines take up to two double arguments and zero // For use in calls that take two double values, constructed either
// or one integer arguments. All are constructed here,
// from r0-r3 or d0 and d1. // from r0-r3 or d0 and d1.
void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { void Simulator::GetFpArgs(double* x, double* y) {
if (use_eabi_hardfloat()) { if (use_eabi_hardfloat()) {
*x = vfp_registers_[0]; *x = vfp_registers_[0];
*y = vfp_registers_[1]; *y = vfp_registers_[1];
*z = registers_[1];
} else { } else {
// We use a char buffer to get around the strict-aliasing rules which // We use a char buffer to get around the strict-aliasing rules which
// otherwise allow the compiler to optimize away the copy. // otherwise allow the compiler to optimize away the copy.
@ -993,9 +991,41 @@ void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
// Registers 2 and 3 -> y. // Registers 2 and 3 -> y.
OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); OS::MemCopy(buffer, registers_ + 2, sizeof(*y));
OS::MemCopy(y, buffer, sizeof(*y)); OS::MemCopy(y, buffer, sizeof(*y));
// Register 2 -> z. }
OS::MemCopy(buffer, registers_ + 2, sizeof(*z)); }
OS::MemCopy(z, buffer, sizeof(*z));
// For use in calls that take one double value, constructed either
// from r0 and r1 or d0.
void Simulator::GetFpArgs(double* x) {
if (use_eabi_hardfloat()) {
*x = vfp_registers_[0];
} else {
// We use a char buffer to get around the strict-aliasing rules which
// otherwise allow the compiler to optimize away the copy.
char buffer[sizeof(*x)];
// Registers 0 and 1 -> x.
OS::MemCopy(buffer, registers_, sizeof(*x));
OS::MemCopy(x, buffer, sizeof(*x));
}
}
// For use in calls that take one double value constructed either
// from r0 and r1 or d0 and one integer value.
void Simulator::GetFpArgs(double* x, int32_t* y) {
if (use_eabi_hardfloat()) {
*x = vfp_registers_[0];
*y = registers_[1];
} else {
// We use a char buffer to get around the strict-aliasing rules which
// otherwise allow the compiler to optimize away the copy.
char buffer[sizeof(*x)];
// Registers 0 and 1 -> x.
OS::MemCopy(buffer, registers_, sizeof(*x));
OS::MemCopy(x, buffer, sizeof(*x));
// Register 2 -> y.
OS::MemCopy(buffer, registers_ + 2, sizeof(*y));
OS::MemCopy(y, buffer, sizeof(*y));
} }
} }
@ -1618,12 +1648,10 @@ typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
int32_t arg3, int32_t arg3,
int32_t arg4, int32_t arg4,
int32_t arg5); int32_t arg5);
typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
// These prototypes handle the four types of FP calls. int32_t arg1,
typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1); int32_t arg2,
typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); int32_t arg3);
typedef double (*SimulatorRuntimeFPCall)(double darg0);
typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
// This signature supports direct call in to API function native callback // This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h). // (refer to InvocationCallback in v8.h).
@ -1689,27 +1717,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
intptr_t external = intptr_t external =
reinterpret_cast<intptr_t>(redirection->external_function()); reinterpret_cast<intptr_t>(redirection->external_function());
if (fp_call) { if (fp_call) {
double dval0, dval1; // one or two double parameters
int32_t ival; // zero or one integer parameters
int64_t iresult = 0; // integer return value
double dresult = 0; // double return value
GetFpArgs(&dval0, &dval1, &ival);
if (::v8::internal::FLAG_trace_sim || !stack_aligned) { if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
SimulatorRuntimeCall generic_target = SimulatorRuntimeFPCall target =
reinterpret_cast<SimulatorRuntimeCall>(external); reinterpret_cast<SimulatorRuntimeFPCall>(external);
double dval0, dval1;
int32_t ival;
switch (redirection->type()) { switch (redirection->type()) {
case ExternalReference::BUILTIN_FP_FP_CALL: case ExternalReference::BUILTIN_FP_FP_CALL:
case ExternalReference::BUILTIN_COMPARE_CALL: case ExternalReference::BUILTIN_COMPARE_CALL:
GetFpArgs(&dval0, &dval1);
PrintF("Call to host function at %p with args %f, %f", PrintF("Call to host function at %p with args %f, %f",
FUNCTION_ADDR(generic_target), dval0, dval1); FUNCTION_ADDR(target), dval0, dval1);
break; break;
case ExternalReference::BUILTIN_FP_CALL: case ExternalReference::BUILTIN_FP_CALL:
GetFpArgs(&dval0);
PrintF("Call to host function at %p with arg %f", PrintF("Call to host function at %p with arg %f",
FUNCTION_ADDR(generic_target), dval0); FUNCTION_ADDR(target), dval0);
break; break;
case ExternalReference::BUILTIN_FP_INT_CALL: case ExternalReference::BUILTIN_FP_INT_CALL:
GetFpArgs(&dval0, &ival);
PrintF("Call to host function at %p with args %f, %d", PrintF("Call to host function at %p with args %f, %d",
FUNCTION_ADDR(generic_target), dval0, ival); FUNCTION_ADDR(target), dval0, ival);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
@ -1721,54 +1749,22 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
PrintF("\n"); PrintF("\n");
} }
CHECK(stack_aligned); CHECK(stack_aligned);
switch (redirection->type()) { if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) {
case ExternalReference::BUILTIN_COMPARE_CALL: {
SimulatorRuntimeCompareCall target =
reinterpret_cast<SimulatorRuntimeCompareCall>(external);
iresult = target(dval0, dval1);
set_register(r0, static_cast<int32_t>(iresult));
set_register(r1, static_cast<int32_t>(iresult >> 32));
break;
}
case ExternalReference::BUILTIN_FP_FP_CALL: {
SimulatorRuntimeFPFPCall target =
reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
dresult = target(dval0, dval1);
SetFpResult(dresult);
break;
}
case ExternalReference::BUILTIN_FP_CALL: {
SimulatorRuntimeFPCall target = SimulatorRuntimeFPCall target =
reinterpret_cast<SimulatorRuntimeFPCall>(external); reinterpret_cast<SimulatorRuntimeFPCall>(external);
dresult = target(dval0); double result = target(arg0, arg1, arg2, arg3);
SetFpResult(dresult); SetFpResult(result);
break; } else {
} SimulatorRuntimeCall target =
case ExternalReference::BUILTIN_FP_INT_CALL: { reinterpret_cast<SimulatorRuntimeCall>(external);
SimulatorRuntimeFPIntCall target = int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
reinterpret_cast<SimulatorRuntimeFPIntCall>(external); int32_t lo_res = static_cast<int32_t>(result);
dresult = target(dval0, ival); int32_t hi_res = static_cast<int32_t>(result >> 32);
SetFpResult(dresult); if (::v8::internal::FLAG_trace_sim) {
break; PrintF("Returned %08x\n", lo_res);
}
default:
UNREACHABLE();
break;
}
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
switch (redirection->type()) {
case ExternalReference::BUILTIN_COMPARE_CALL:
PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
break;
case ExternalReference::BUILTIN_FP_FP_CALL:
case ExternalReference::BUILTIN_FP_CALL:
case ExternalReference::BUILTIN_FP_INT_CALL:
PrintF("Returned %f\n", dresult);
break;
default:
UNREACHABLE();
break;
} }
set_register(r0, lo_res);
set_register(r1, hi_res);
} }
} else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
SimulatorRuntimeDirectApiCall target = SimulatorRuntimeDirectApiCall target =

6
deps/v8/src/arm/simulator-arm.h

@ -348,8 +348,10 @@ class Simulator {
void* external_function, void* external_function,
v8::internal::ExternalReference::Type type); v8::internal::ExternalReference::Type type);
// Handle arguments and return value for runtime FP functions. // For use in calls that take double value arguments.
void GetFpArgs(double* x, double* y, int32_t* z); void GetFpArgs(double* x, double* y);
void GetFpArgs(double* x);
void GetFpArgs(double* x, int32_t* y);
void SetFpResult(const double& result); void SetFpResult(const double& result);
void TrashCallerSaveRegisters(); void TrashCallerSaveRegisters();

2
deps/v8/src/atomicops_internals_x86_gcc.h

@ -168,7 +168,7 @@ inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
return *ptr; return *ptr;
} }
#if defined(__x86_64__) && defined(V8_HOST_ARCH_64_BIT) #if defined(__x86_64__)
// 64-bit low-level operations on 64-bit platform. // 64-bit low-level operations on 64-bit platform.

34
deps/v8/src/builtins.cc

@ -125,31 +125,23 @@ BUILTIN_LIST_C(DEF_ARG_TYPE)
#ifdef DEBUG #ifdef DEBUG
#define BUILTIN(name) \ #define BUILTIN(name) \
MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate); \ name##ArgumentsType args, Isolate* isolate); \
MUST_USE_RESULT static MaybeObject* Builtin_##name( \ MUST_USE_RESULT static MaybeObject* Builtin_##name( \
int args_length, Object** args_object, Isolate* isolate) { \ name##ArgumentsType args, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \ ASSERT(isolate == Isolate::Current()); \
ASSERT(isolate == Isolate::Current()); \ args.Verify(); \
args.Verify(); \ return Builtin_Impl_##name(args, isolate); \
return Builtin_Impl_##name(args, isolate); \ } \
} \ MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate) name##ArgumentsType args, Isolate* isolate)
#else // For release mode. #else // For release mode.
#define BUILTIN(name) \ #define BUILTIN(name) \
static MaybeObject* Builtin_impl##name( \ static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate)
name##ArgumentsType args, Isolate* isolate); \
static MaybeObject* Builtin_##name( \
int args_length, Object** args_object, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \
return Builtin_impl##name(args, isolate); \
} \
static MaybeObject* Builtin_impl##name( \
name##ArgumentsType args, Isolate* isolate)
#endif #endif

2
deps/v8/src/builtins.h

@ -274,6 +274,8 @@ enum BuiltinExtraArguments {
V(APPLY_PREPARE, 1) \ V(APPLY_PREPARE, 1) \
V(APPLY_OVERFLOW, 1) V(APPLY_OVERFLOW, 1)
MaybeObject* ArrayConstructor_StubFailure(Arguments args, Isolate* isolate);
class BuiltinFunctionTable; class BuiltinFunctionTable;
class ObjectVisitor; class ObjectVisitor;

23
deps/v8/src/code-stubs-hydrogen.cc

@ -106,8 +106,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
Zone* zone = this->zone(); Zone* zone = this->zone();
int param_count = descriptor_->register_param_count_; int param_count = descriptor_->register_param_count_;
HEnvironment* start_environment = graph()->start_environment(); HEnvironment* start_environment = graph()->start_environment();
HBasicBlock* next_block = HBasicBlock* next_block = CreateBasicBlock(start_environment);
CreateBasicBlock(start_environment, BailoutId::StubEntry());
current_block()->Goto(next_block); current_block()->Goto(next_block);
next_block->SetJoinId(BailoutId::StubEntry()); next_block->SetJoinId(BailoutId::StubEntry());
set_current_block(next_block); set_current_block(next_block);
@ -186,7 +185,7 @@ template <class Stub>
static Handle<Code> DoGenerateCode(Stub* stub) { static Handle<Code> DoGenerateCode(Stub* stub) {
CodeStubGraphBuilder<Stub> builder(stub); CodeStubGraphBuilder<Stub> builder(stub);
LChunk* chunk = OptimizeGraph(builder.CreateGraph()); LChunk* chunk = OptimizeGraph(builder.CreateGraph());
return chunk->Codegen(Code::COMPILED_STUB); return chunk->Codegen();
} }
@ -212,23 +211,24 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
IfBuilder if_fixed_cow(this); IfBuilder if_fixed_cow(this);
if_fixed_cow.BeginIfMapEquals(elements, factory->fixed_cow_array_map()); if_fixed_cow.IfCompareMap(elements, factory->fixed_cow_array_map());
if_fixed_cow.Then();
environment()->Push(BuildCloneShallowArray(context(), environment()->Push(BuildCloneShallowArray(context(),
boilerplate, boilerplate,
alloc_site_mode, alloc_site_mode,
FAST_ELEMENTS, FAST_ELEMENTS,
0/*copy-on-write*/)); 0/*copy-on-write*/));
if_fixed_cow.BeginElse(); if_fixed_cow.Else();
IfBuilder if_fixed(this); IfBuilder if_fixed(this);
if_fixed.BeginIfMapEquals(elements, factory->fixed_array_map()); if_fixed.IfCompareMap(elements, factory->fixed_array_map());
if_fixed.Then();
environment()->Push(BuildCloneShallowArray(context(), environment()->Push(BuildCloneShallowArray(context(),
boilerplate, boilerplate,
alloc_site_mode, alloc_site_mode,
FAST_ELEMENTS, FAST_ELEMENTS,
length)); length));
if_fixed.BeginElse(); if_fixed.Else();
environment()->Push(BuildCloneShallowArray(context(), environment()->Push(BuildCloneShallowArray(context(),
boilerplate, boilerplate,
alloc_site_mode, alloc_site_mode,
@ -250,7 +250,7 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
Handle<Code> FastCloneShallowArrayStub::GenerateCode() { Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
CodeStubGraphBuilder<FastCloneShallowArrayStub> builder(this); CodeStubGraphBuilder<FastCloneShallowArrayStub> builder(this);
LChunk* chunk = OptimizeGraph(builder.CreateGraph()); LChunk* chunk = OptimizeGraph(builder.CreateGraph());
return chunk->Codegen(Code::COMPILED_STUB); return chunk->Codegen();
} }
@ -359,11 +359,12 @@ HValue* CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() {
IfBuilder if_builder(this); IfBuilder if_builder(this);
if_builder.BeginIf(array_length, graph()->GetConstant0(), Token::EQ); if_builder.IfCompare(array_length, graph()->GetConstant0(), Token::EQ);
if_builder.Then();
// Nothing to do, just change the map. // Nothing to do, just change the map.
if_builder.BeginElse(); if_builder.Else();
HInstruction* elements = HInstruction* elements =
AddInstruction(new(zone) HLoadElements(js_array, js_array)); AddInstruction(new(zone) HLoadElements(js_array, js_array));

6
deps/v8/src/code-stubs.cc

@ -67,7 +67,7 @@ void CodeStub::RecordCodeGeneration(Code* code, Isolate* isolate) {
} }
int CodeStub::GetCodeKind() { Code::Kind CodeStub::GetCodeKind() const {
return Code::STUB; return Code::STUB;
} }
@ -98,7 +98,7 @@ Handle<Code> PlatformCodeStub::GenerateCode() {
// Copy the generated code into a heap object. // Copy the generated code into a heap object.
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
static_cast<Code::Kind>(GetCodeKind()), GetCodeKind(),
GetICState(), GetICState(),
GetExtraICState(), GetExtraICState(),
GetStubType(), GetStubType(),
@ -308,7 +308,7 @@ void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
static_cast<Code::Kind>(GetCodeKind()), GetCodeKind(),
UNINITIALIZED); UNINITIALIZED);
ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT); ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT);
Handle<Object> probe( Handle<Object> probe(

30
deps/v8/src/code-stubs.h

@ -176,19 +176,19 @@ class CodeStub BASE_EMBEDDED {
virtual Major MajorKey() = 0; virtual Major MajorKey() = 0;
virtual int MinorKey() = 0; virtual int MinorKey() = 0;
protected:
static bool CanUseFPRegisters();
// Generates the assembler code for the stub.
virtual Handle<Code> GenerateCode() = 0;
// BinaryOpStub needs to override this.
virtual InlineCacheState GetICState() { virtual InlineCacheState GetICState() {
return UNINITIALIZED; return UNINITIALIZED;
} }
virtual Code::ExtraICState GetExtraICState() { virtual Code::ExtraICState GetExtraICState() {
return Code::kNoExtraICState; return Code::kNoExtraICState;
} }
protected:
static bool CanUseFPRegisters();
// Generates the assembler code for the stub.
virtual Handle<Code> GenerateCode() = 0;
virtual Code::StubType GetStubType() { virtual Code::StubType GetStubType() {
return Code::NORMAL; return Code::NORMAL;
} }
@ -210,7 +210,7 @@ class CodeStub BASE_EMBEDDED {
virtual void Activate(Code* code) { } virtual void Activate(Code* code) { }
// BinaryOpStub needs to override this. // BinaryOpStub needs to override this.
virtual int GetCodeKind(); virtual Code::Kind GetCodeKind() const;
// Add the code to a specialized cache, specific to an individual // Add the code to a specialized cache, specific to an individual
// stub type. Please note, this method must add the code object to a // stub type. Please note, this method must add the code object to a
@ -249,7 +249,7 @@ class PlatformCodeStub : public CodeStub {
// Retrieve the code for the stub. Generate the code if needed. // Retrieve the code for the stub. Generate the code if needed.
virtual Handle<Code> GenerateCode(); virtual Handle<Code> GenerateCode();
virtual int GetCodeKind() { return Code::STUB; } virtual Code::Kind GetCodeKind() const { return Code::STUB; }
virtual int GetStubFlags() { return -1; } virtual int GetStubFlags() { return -1; }
protected: protected:
@ -286,7 +286,7 @@ class HydrogenCodeStub : public CodeStub {
// Retrieve the code for the stub. Generate the code if needed. // Retrieve the code for the stub. Generate the code if needed.
virtual Handle<Code> GenerateCode() = 0; virtual Handle<Code> GenerateCode() = 0;
virtual int GetCodeKind() { return Code::COMPILED_STUB; } virtual Code::Kind GetCodeKind() const { return Code::STUB; }
CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate) { CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate) {
return isolate->code_stub_interface_descriptor(MajorKey()); return isolate->code_stub_interface_descriptor(MajorKey());
@ -606,7 +606,7 @@ class MathPowStub: public PlatformCodeStub {
class ICStub: public PlatformCodeStub { class ICStub: public PlatformCodeStub {
public: public:
explicit ICStub(Code::Kind kind) : kind_(kind) { } explicit ICStub(Code::Kind kind) : kind_(kind) { }
virtual int GetCodeKind() { return kind_; } virtual Code::Kind GetCodeKind() const { return kind_; }
virtual InlineCacheState GetICState() { return MONOMORPHIC; } virtual InlineCacheState GetICState() { return MONOMORPHIC; }
bool Describes(Code* code) { bool Describes(Code* code) {
@ -692,7 +692,7 @@ class StoreArrayLengthStub: public StoreICStub {
class HandlerStub: public ICStub { class HandlerStub: public ICStub {
public: public:
explicit HandlerStub(Code::Kind kind) : ICStub(kind) { } explicit HandlerStub(Code::Kind kind) : ICStub(kind) { }
virtual int GetCodeKind() { return Code::STUB; } virtual Code::Kind GetCodeKind() const { return Code::STUB; }
virtual int GetStubFlags() { return kind(); } virtual int GetStubFlags() { return kind(); }
}; };
@ -830,7 +830,7 @@ class BinaryOpStub: public PlatformCodeStub {
// Entirely platform-specific methods are defined as static helper // Entirely platform-specific methods are defined as static helper
// functions in the <arch>/code-stubs-<arch>.cc files. // functions in the <arch>/code-stubs-<arch>.cc files.
virtual int GetCodeKind() { return Code::BINARY_OP_IC; } virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; }
virtual InlineCacheState GetICState() { virtual InlineCacheState GetICState() {
return BinaryOpIC::ToState(Max(left_type_, right_type_)); return BinaryOpIC::ToState(Max(left_type_, right_type_));
@ -884,7 +884,7 @@ class ICCompareStub: public PlatformCodeStub {
virtual CodeStub::Major MajorKey() { return CompareIC; } virtual CodeStub::Major MajorKey() { return CompareIC; }
virtual int MinorKey(); virtual int MinorKey();
virtual int GetCodeKind() { return Code::COMPARE_IC; } virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; }
void GenerateSmis(MacroAssembler* masm); void GenerateSmis(MacroAssembler* masm);
void GenerateNumbers(MacroAssembler* masm); void GenerateNumbers(MacroAssembler* masm);
@ -1548,7 +1548,7 @@ class ToBooleanStub: public PlatformCodeStub {
: tos_(tos), types_(types) { } : tos_(tos), types_(types) { }
void Generate(MacroAssembler* masm); void Generate(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TO_BOOLEAN_IC; } virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; }
virtual void PrintName(StringStream* stream); virtual void PrintName(StringStream* stream);
virtual bool SometimesSetsUpAFrame() { return false; } virtual bool SometimesSetsUpAFrame() { return false; }

9
deps/v8/src/codegen.cc

@ -106,10 +106,13 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
// Allocate and install the code. // Allocate and install the code.
CodeDesc desc; CodeDesc desc;
bool is_crankshafted =
Code::ExtractKindFromFlags(flags) == Code::OPTIMIZED_FUNCTION ||
info->IsStub();
masm->GetCode(&desc); masm->GetCode(&desc);
Handle<Code> code = Handle<Code> code =
isolate->factory()->NewCode(desc, flags, masm->CodeObject()); isolate->factory()->NewCode(desc, flags, masm->CodeObject(),
false, is_crankshafted);
if (!code.is_null()) { if (!code.is_null()) {
isolate->counters()->total_compiled_code_size()->Increment( isolate->counters()->total_compiled_code_size()->Increment(
code->instruction_size()); code->instruction_size());
@ -129,7 +132,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
if (print_code) { if (print_code) {
// Print the source code if available. // Print the source code if available.
FunctionLiteral* function = info->function(); FunctionLiteral* function = info->function();
if (code->kind() != Code::COMPILED_STUB) { if (code->kind() == Code::OPTIMIZED_FUNCTION) {
Handle<Script> script = info->script(); Handle<Script> script = info->script();
if (!script->IsUndefined() && !script->source()->IsUndefined()) { if (!script->IsUndefined() && !script->source()->IsUndefined()) {
PrintF("--- Raw source ---\n"); PrintF("--- Raw source ---\n");

10
deps/v8/src/compiler.cc

@ -144,7 +144,11 @@ int CompilationInfo::num_heap_slots() const {
Code::Flags CompilationInfo::flags() const { Code::Flags CompilationInfo::flags() const {
if (IsStub()) { if (IsStub()) {
return Code::ComputeFlags(Code::COMPILED_STUB); return Code::ComputeFlags(code_stub()->GetCodeKind(),
code_stub()->GetICState(),
code_stub()->GetExtraICState(),
Code::NORMAL,
0);
} else { } else {
return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
} }
@ -421,7 +425,7 @@ OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() {
Timer timer(this, &time_taken_to_codegen_); Timer timer(this, &time_taken_to_codegen_);
ASSERT(chunk_ != NULL); ASSERT(chunk_ != NULL);
ASSERT(graph_ != NULL); ASSERT(graph_ != NULL);
Handle<Code> optimized_code = chunk_->Codegen(Code::OPTIMIZED_FUNCTION); Handle<Code> optimized_code = chunk_->Codegen();
if (optimized_code.is_null()) { if (optimized_code.is_null()) {
info()->set_bailout_reason("code generation failed"); info()->set_bailout_reason("code generation failed");
return AbortOptimization(); return AbortOptimization();
@ -553,6 +557,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
isolate->factory()->NewSharedFunctionInfo( isolate->factory()->NewSharedFunctionInfo(
lit->name(), lit->name(),
lit->materialized_literal_count(), lit->materialized_literal_count(),
lit->is_generator(),
info->code(), info->code(),
ScopeInfo::Create(info->scope(), info->zone())); ScopeInfo::Create(info->scope(), info->zone()));
@ -1074,6 +1079,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
Handle<SharedFunctionInfo> result = Handle<SharedFunctionInfo> result =
FACTORY->NewSharedFunctionInfo(literal->name(), FACTORY->NewSharedFunctionInfo(literal->name(),
literal->materialized_literal_count(), literal->materialized_literal_count(),
literal->is_generator(),
info.code(), info.code(),
scope_info); scope_info);
SetFunctionInfo(result, literal, false, script); SetFunctionInfo(result, literal, false, script);

2
deps/v8/src/compiler.h

@ -79,7 +79,7 @@ class CompilationInfo {
Handle<JSFunction> closure() const { return closure_; } Handle<JSFunction> closure() const { return closure_; }
Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
Handle<Script> script() const { return script_; } Handle<Script> script() const { return script_; }
HydrogenCodeStub* code_stub() {return code_stub_; } HydrogenCodeStub* code_stub() const {return code_stub_; }
v8::Extension* extension() const { return extension_; } v8::Extension* extension() const { return extension_; }
ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; } ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
Handle<Context> context() const { return context_; } Handle<Context> context() const { return context_; }

5
deps/v8/src/deoptimizer.cc

@ -1195,7 +1195,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// reg = JSFunction context // reg = JSFunction context
// //
ASSERT(compiled_code_->kind() == Code::COMPILED_STUB); ASSERT(compiled_code_->is_crankshafted() &&
compiled_code_->kind() != Code::OPTIMIZED_FUNCTION);
int major_key = compiled_code_->major_key(); int major_key = compiled_code_->major_key();
CodeStubInterfaceDescriptor* descriptor = CodeStubInterfaceDescriptor* descriptor =
isolate_->code_stub_interface_descriptor(major_key); isolate_->code_stub_interface_descriptor(major_key);
@ -2133,7 +2134,7 @@ unsigned Deoptimizer::ComputeInputFrameSize() const {
// size matches with the stack height we can compute based on the // size matches with the stack height we can compute based on the
// environment at the OSR entry. The code for that his built into // environment at the OSR entry. The code for that his built into
// the DoComputeOsrOutputFrame function for now. // the DoComputeOsrOutputFrame function for now.
} else if (compiled_code_->kind() != Code::COMPILED_STUB) { } else if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
unsigned stack_slots = compiled_code_->stack_slots(); unsigned stack_slots = compiled_code_->stack_slots();
unsigned outgoing_size = ComputeOutgoingArgumentSize(); unsigned outgoing_size = ComputeOutgoingArgumentSize();
ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);

3
deps/v8/src/disassembler.cc

@ -332,8 +332,7 @@ int Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) {
// Called by Code::CodePrint. // Called by Code::CodePrint.
void Disassembler::Decode(FILE* f, Code* code) { void Disassembler::Decode(FILE* f, Code* code) {
Isolate* isolate = code->GetIsolate(); Isolate* isolate = code->GetIsolate();
int decode_size = (code->kind() == Code::OPTIMIZED_FUNCTION || int decode_size = code->is_crankshafted()
code->kind() == Code::COMPILED_STUB)
? static_cast<int>(code->safepoint_table_offset()) ? static_cast<int>(code->safepoint_table_offset())
: code->instruction_size(); : code->instruction_size();
// If there might be a back edge table, stop before reaching it. // If there might be a back edge table, stop before reaching it.

11
deps/v8/src/factory.cc

@ -1,4 +1,4 @@
// Copyright 2012 the V8 project authors. All rights reserved. // Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -916,10 +916,11 @@ Handle<JSObject> Factory::NewExternal(void* value) {
Handle<Code> Factory::NewCode(const CodeDesc& desc, Handle<Code> Factory::NewCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_ref, Handle<Object> self_ref,
bool immovable) { bool immovable,
bool crankshafted) {
CALL_HEAP_FUNCTION(isolate(), CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->CreateCode( isolate()->heap()->CreateCode(
desc, flags, self_ref, immovable), desc, flags, self_ref, immovable, crankshafted),
Code); Code);
} }
@ -1078,6 +1079,7 @@ void Factory::SetIdentityHash(Handle<JSObject> object, Smi* hash) {
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name, Handle<String> name,
int number_of_literals, int number_of_literals,
bool is_generator,
Handle<Code> code, Handle<Code> code,
Handle<ScopeInfo> scope_info) { Handle<ScopeInfo> scope_info) {
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name); Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
@ -1091,6 +1093,9 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
literals_array_size += JSFunction::kLiteralsPrefixSize; literals_array_size += JSFunction::kLiteralsPrefixSize;
} }
shared->set_num_literals(literals_array_size); shared->set_num_literals(literals_array_size);
if (is_generator) {
shared->set_instance_class_name(isolate()->heap()->Generator_string());
}
return shared; return shared;
} }

4
deps/v8/src/factory.h

@ -347,7 +347,8 @@ class Factory {
Handle<Code> NewCode(const CodeDesc& desc, Handle<Code> NewCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_reference, Handle<Object> self_reference,
bool immovable = false); bool immovable = false,
bool crankshafted = false);
Handle<Code> CopyCode(Handle<Code> code); Handle<Code> CopyCode(Handle<Code> code);
@ -454,6 +455,7 @@ class Factory {
Handle<SharedFunctionInfo> NewSharedFunctionInfo( Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name, Handle<String> name,
int number_of_literals, int number_of_literals,
bool is_generator,
Handle<Code> code, Handle<Code> code,
Handle<ScopeInfo> scope_info); Handle<ScopeInfo> scope_info);
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name); Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);

20
deps/v8/src/generator.js

@ -39,18 +39,38 @@
// http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png // http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png
function GeneratorObjectNext() { function GeneratorObjectNext() {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.next', this]);
}
// TODO(wingo): Implement. // TODO(wingo): Implement.
} }
function GeneratorObjectSend(value) { function GeneratorObjectSend(value) {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.send', this]);
}
// TODO(wingo): Implement. // TODO(wingo): Implement.
} }
function GeneratorObjectThrow(exn) { function GeneratorObjectThrow(exn) {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.throw', this]);
}
// TODO(wingo): Implement. // TODO(wingo): Implement.
} }
function GeneratorObjectClose() { function GeneratorObjectClose() {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.close', this]);
}
// TODO(wingo): Implement. // TODO(wingo): Implement.
} }

7
deps/v8/src/heap-inl.h

@ -623,6 +623,13 @@ Isolate* Heap::isolate() {
CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return) CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return)
#define CALL_HEAP_FUNCTION_PASS_EXCEPTION(ISOLATE, FUNCTION_CALL) \
CALL_AND_RETRY(ISOLATE, \
FUNCTION_CALL, \
return __object__, \
return __maybe_object__)
#ifdef DEBUG #ifdef DEBUG
inline bool Heap::allow_allocation(bool new_state) { inline bool Heap::allow_allocation(bool new_state) {

5
deps/v8/src/heap.cc

@ -3752,7 +3752,8 @@ MaybeObject* Heap::AllocateExternalArray(int length,
MaybeObject* Heap::CreateCode(const CodeDesc& desc, MaybeObject* Heap::CreateCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_reference, Handle<Object> self_reference,
bool immovable) { bool immovable,
bool crankshafted) {
// Allocate ByteArray before the Code object, so that we do not risk // Allocate ByteArray before the Code object, so that we do not risk
// leaving uninitialized Code object (and breaking the heap). // leaving uninitialized Code object (and breaking the heap).
ByteArray* reloc_info; ByteArray* reloc_info;
@ -3796,6 +3797,7 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
if (code->is_call_stub() || code->is_keyed_call_stub()) { if (code->is_call_stub() || code->is_keyed_call_stub()) {
code->set_check_type(RECEIVER_MAP_CHECK); code->set_check_type(RECEIVER_MAP_CHECK);
} }
code->set_is_crankshafted(crankshafted);
code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
code->InitializeTypeFeedbackInfoNoWriteBarrier(undefined_value()); code->InitializeTypeFeedbackInfoNoWriteBarrier(undefined_value());
code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
@ -4358,6 +4360,7 @@ MaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) {
MaybeObject* maybe_map = AllocateInitialMap(function); MaybeObject* maybe_map = AllocateInitialMap(function);
if (!maybe_map->To(&map)) return maybe_map; if (!maybe_map->To(&map)) return maybe_map;
function->set_initial_map(map); function->set_initial_map(map);
map->set_constructor(function);
} }
ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE); ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
return AllocateJSObjectFromMap(map); return AllocateJSObjectFromMap(map);

6
deps/v8/src/heap.h

@ -268,7 +268,8 @@ namespace internal {
V(infinity_string, "Infinity") \ V(infinity_string, "Infinity") \
V(minus_infinity_string, "-Infinity") \ V(minus_infinity_string, "-Infinity") \
V(hidden_stack_trace_string, "v8::hidden_stack_trace") \ V(hidden_stack_trace_string, "v8::hidden_stack_trace") \
V(query_colon_string, "(?:)") V(query_colon_string, "(?:)") \
V(Generator_string, "Generator")
// Forward declarations. // Forward declarations.
class GCTracer; class GCTracer;
@ -1141,7 +1142,8 @@ class Heap {
MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc, MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_reference, Handle<Object> self_reference,
bool immovable = false); bool immovable = false,
bool crankshafted = false);
MUST_USE_RESULT MaybeObject* CopyCode(Code* code); MUST_USE_RESULT MaybeObject* CopyCode(Code* code);

45
deps/v8/src/hydrogen-instructions.cc

@ -648,6 +648,11 @@ int32_t HValue::GetInteger32Constant() {
} }
bool HValue::EqualsInteger32Constant(int32_t value) {
return IsInteger32Constant() && GetInteger32Constant() == value;
}
void HValue::SetOperandAt(int index, HValue* value) { void HValue::SetOperandAt(int index, HValue* value) {
RegisterUse(index, value); RegisterUse(index, value);
InternalSetOperandAt(index, value); InternalSetOperandAt(index, value);
@ -1393,15 +1398,11 @@ HValue* HBitwise::Canonicalize() {
if (!representation().IsInteger32()) return this; if (!representation().IsInteger32()) return this;
// If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
if (left()->IsConstant() && if (left()->EqualsInteger32Constant(nop_constant) &&
HConstant::cast(left())->HasInteger32Value() &&
HConstant::cast(left())->Integer32Value() == nop_constant &&
!right()->CheckFlag(kUint32)) { !right()->CheckFlag(kUint32)) {
return right(); return right();
} }
if (right()->IsConstant() && if (right()->EqualsInteger32Constant(nop_constant) &&
HConstant::cast(right())->HasInteger32Value() &&
HConstant::cast(right())->Integer32Value() == nop_constant &&
!left()->CheckFlag(kUint32)) { !left()->CheckFlag(kUint32)) {
return left(); return left();
} }
@ -1422,17 +1423,37 @@ HValue* HBitNot::Canonicalize() {
} }
HValue* HAdd::Canonicalize() { HValue* HArithmeticBinaryOperation::Canonicalize() {
if (!representation().IsInteger32()) return this; if (representation().IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) {
if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); ClearFlag(kCanOverflow);
}
return this; return this;
} }
static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) {
return arg1->representation().IsSpecialization() &&
arg2->EqualsInteger32Constant(identity);
}
HValue* HAdd::Canonicalize() {
if (IsIdentityOperation(left(), right(), 0)) return left();
if (IsIdentityOperation(right(), left(), 0)) return right();
return HArithmeticBinaryOperation::Canonicalize();
}
HValue* HSub::Canonicalize() { HValue* HSub::Canonicalize() {
if (!representation().IsInteger32()) return this; if (IsIdentityOperation(left(), right(), 0)) return left();
if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); return HArithmeticBinaryOperation::Canonicalize();
return this; }
HValue* HMul::Canonicalize() {
if (IsIdentityOperation(left(), right(), 1)) return left();
if (IsIdentityOperation(right(), left(), 1)) return right();
return HArithmeticBinaryOperation::Canonicalize();
} }

9
deps/v8/src/hydrogen-instructions.h

@ -1001,6 +1001,7 @@ class HValue: public ZoneObject {
bool IsInteger32Constant(); bool IsInteger32Constant();
int32_t GetInteger32Constant(); int32_t GetInteger32Constant();
bool EqualsInteger32Constant(int32_t value);
bool IsDefinedAfter(HBasicBlock* other) const; bool IsDefinedAfter(HBasicBlock* other) const;
@ -3328,10 +3329,6 @@ class HConstant: public HTemplateInstruction<0> {
bool BooleanValue() const { return boolean_value_; } bool BooleanValue() const { return boolean_value_; }
bool IsUint32() {
return HasInteger32Value() && (Integer32Value() >= 0);
}
virtual intptr_t Hashcode() { virtual intptr_t Hashcode() {
if (has_int32_value_) { if (has_int32_value_) {
return static_cast<intptr_t>(int32_value_); return static_cast<intptr_t>(int32_value_);
@ -3842,6 +3839,8 @@ class HArithmeticBinaryOperation: public HBinaryOperation {
: representation(); : representation();
} }
virtual HValue* Canonicalize();
private: private:
virtual bool IsDeletable() const { return true; } virtual bool IsDeletable() const { return true; }
}; };
@ -4401,6 +4400,8 @@ class HMul: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual HValue* Canonicalize();
// Only commutative if it is certain that not two objects are multiplicated. // Only commutative if it is certain that not two objects are multiplicated.
virtual bool IsCommutative() const { virtual bool IsCommutative() const {
return !representation().IsTagged(); return !representation().IsTagged();

453
deps/v8/src/hydrogen.cc

@ -113,11 +113,10 @@ void HBasicBlock::AddInstruction(HInstruction* instr) {
ASSERT(!IsStartBlock() || !IsFinished()); ASSERT(!IsStartBlock() || !IsFinished());
ASSERT(!instr->IsLinked()); ASSERT(!instr->IsLinked());
ASSERT(!IsFinished()); ASSERT(!IsFinished());
// Make sure that we never add instructions without knowing
// what the previous ast id is.
ASSERT(instr->IsSimulate() || instr->IsGoto() ||
!last_environment()->previous_ast_id().IsNone());
if (first_ == NULL) { if (first_ == NULL) {
ASSERT(last_environment() != NULL);
ASSERT(!last_environment()->ast_id().IsNone());
HBlockEntry* entry = new(zone()) HBlockEntry(); HBlockEntry* entry = new(zone()) HBlockEntry();
entry->InitializeAsFirst(this); entry->InitializeAsFirst(this);
first_ = last_ = entry; first_ = last_ = entry;
@ -184,7 +183,9 @@ void HBasicBlock::Finish(HControlInstruction* end) {
} }
void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { void HBasicBlock::Goto(HBasicBlock* block,
FunctionState* state,
bool add_simulate) {
bool drop_extra = state != NULL && bool drop_extra = state != NULL &&
state->inlining_kind() == DROP_EXTRA_ON_RETURN; state->inlining_kind() == DROP_EXTRA_ON_RETURN;
@ -193,7 +194,7 @@ void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) {
last_environment_ = last_environment()->DiscardInlined(drop_extra); last_environment_ = last_environment()->DiscardInlined(drop_extra);
} }
AddSimulate(BailoutId::None()); if (add_simulate) AddSimulate(BailoutId::None());
HGoto* instr = new(zone()) HGoto(block); HGoto* instr = new(zone()) HGoto(block);
Finish(instr); Finish(instr);
} }
@ -215,12 +216,10 @@ void HBasicBlock::AddLeaveInlined(HValue* return_value,
} }
void HBasicBlock::SetInitialEnvironment(HEnvironment* env, void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
BailoutId previous_ast_id) {
ASSERT(!HasEnvironment()); ASSERT(!HasEnvironment());
ASSERT(first() == NULL); ASSERT(first() == NULL);
UpdateEnvironment(env); UpdateEnvironment(env);
env->set_previous_ast_id(previous_ast_id);
} }
@ -236,11 +235,7 @@ void HBasicBlock::SetJoinId(BailoutId ast_id) {
predecessor->last_environment()->closure()->shared() predecessor->last_environment()->closure()->shared()
->VerifyBailoutId(ast_id))); ->VerifyBailoutId(ast_id)));
simulate->set_ast_id(ast_id); simulate->set_ast_id(ast_id);
} predecessor->last_environment()->set_ast_id(ast_id);
HEnvironment* last_environment = this->last_environment();
ASSERT(last_environment || IsFinished());
if (last_environment != NULL) {
last_environment->set_previous_ast_id(ast_id);
} }
} }
@ -301,9 +296,7 @@ void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
} }
} else if (!HasEnvironment() && !IsFinished()) { } else if (!HasEnvironment() && !IsFinished()) {
ASSERT(!IsLoopHeader()); ASSERT(!IsLoopHeader());
HEnvironment* new_env = pred->last_environment()->Copy(); SetInitialEnvironment(pred->last_environment()->Copy());
SetInitialEnvironment(new_env,
pred->last_environment()->previous_ast_id());
} }
predecessors_.Add(pred, zone()); predecessors_.Add(pred, zone());
@ -553,6 +546,18 @@ void HGraph::Verify(bool do_full_verify) const {
HPhi* phi = block->phis()->at(j); HPhi* phi = block->phis()->at(j);
phi->Verify(); phi->Verify();
} }
// Check that all join blocks have predecessors that end with an
// unconditional goto and agree on their environment node id.
if (block->predecessors()->length() >= 2) {
BailoutId id =
block->predecessors()->first()->last_environment()->ast_id();
for (int k = 0; k < block->predecessors()->length(); k++) {
HBasicBlock* predecessor = block->predecessors()->at(k);
ASSERT(predecessor->end()->IsGoto());
ASSERT(predecessor->last_environment()->ast_id() == id);
}
}
} }
// Check special property of first block to have no predecessors. // Check special property of first block to have no predecessors.
@ -639,25 +644,24 @@ DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder)
: builder_(builder), : builder_(builder),
finished_(false), finished_(false) {
id_(builder->current_block()->last_environment()->previous_ast_id()) {
HEnvironment* env = builder->environment(); HEnvironment* env = builder->environment();
failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); failure_block_ = builder->CreateBasicBlock(env->Copy());
merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); merge_block_ = builder->CreateBasicBlock(env->Copy());
} }
HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) {
HEnvironment* env = builder_->environment(); HEnvironment* env = builder_->environment();
HIsNilAndBranch* compare = HCompareObjectEqAndBranch* compare =
new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); new(zone()) HCompareObjectEqAndBranch(
HBasicBlock* success_block = value,
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); builder_->graph()->GetConstantUndefined());
HBasicBlock* failure_block = HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy());
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy());
compare->SetSuccessorAt(0, failure_block); compare->SetSuccessorAt(0, failure_block);
compare->SetSuccessorAt(1, success_block); compare->SetSuccessorAt(1, success_block);
failure_block->Goto(failure_block_); failure_block->GotoNoSimulate(failure_block_);
builder_->current_block()->Finish(compare); builder_->current_block()->Finish(compare);
builder_->set_current_block(success_block); builder_->set_current_block(success_block);
return compare; return compare;
@ -671,13 +675,11 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left,
HCompareIDAndBranch* compare = HCompareIDAndBranch* compare =
new(zone()) HCompareIDAndBranch(left, right, op); new(zone()) HCompareIDAndBranch(left, right, op);
compare->AssumeRepresentation(Representation::Integer32()); compare->AssumeRepresentation(Representation::Integer32());
HBasicBlock* success_block = HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy());
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy());
HBasicBlock* failure_block =
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_);
compare->SetSuccessorAt(0, success_block); compare->SetSuccessorAt(0, success_block);
compare->SetSuccessorAt(1, failure_block); compare->SetSuccessorAt(1, failure_block);
failure_block->Goto(failure_block_); failure_block->GotoNoSimulate(failure_block_);
builder_->current_block()->Finish(compare); builder_->current_block()->Finish(compare);
builder_->set_current_block(success_block); builder_->set_current_block(success_block);
return compare; return compare;
@ -692,11 +694,11 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left,
void HGraphBuilder::CheckBuilder::End() { void HGraphBuilder::CheckBuilder::End() {
ASSERT(!finished_); ASSERT(!finished_);
builder_->current_block()->Goto(merge_block_); builder_->current_block()->GotoNoSimulate(merge_block_);
failure_block_->SetJoinId(id_); if (failure_block_->HasPredecessor()) {
failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
}
builder_->set_current_block(merge_block_); builder_->set_current_block(merge_block_);
merge_block_->SetJoinId(id_);
finished_ = true; finished_ = true;
} }
@ -706,19 +708,51 @@ HConstant* HGraph::GetInvalidContext() {
} }
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
: builder_(builder), : builder_(builder),
position_(position),
finished_(false), finished_(false),
did_then_(false),
did_else_(false), did_else_(false),
id_(builder->current_block()->last_environment()->previous_ast_id()) { deopt_then_(false),
deopt_else_(false),
did_and_(false),
did_or_(false),
captured_(false),
needs_compare_(true),
split_edge_merge_block_(NULL) {
HEnvironment* env = builder->environment(); HEnvironment* env = builder->environment();
first_true_block_ = builder->CreateBasicBlock(env->Copy(), id_); first_true_block_ = builder->CreateBasicBlock(env->Copy());
last_true_block_ = NULL; last_true_block_ = NULL;
first_false_block_ = builder->CreateBasicBlock(env->Copy(), id_); first_false_block_ = builder->CreateBasicBlock(env->Copy());
} }
HInstruction* HGraphBuilder::IfBuilder::BeginIf( HGraphBuilder::IfBuilder::IfBuilder(
HGraphBuilder* builder,
HIfContinuation* continuation)
: builder_(builder),
position_(RelocInfo::kNoPosition),
finished_(false),
did_then_(false),
did_else_(false),
deopt_then_(false),
deopt_else_(false),
did_and_(false),
did_or_(false),
captured_(false),
needs_compare_(false),
first_true_block_(NULL),
first_false_block_(NULL),
split_edge_merge_block_(NULL),
merge_block_(NULL) {
continuation->Continue(&first_true_block_,
&first_false_block_,
&position_);
}
HInstruction* HGraphBuilder::IfBuilder::IfCompare(
HValue* left, HValue* left,
HValue* right, HValue* right,
Token::Value token, Token::Value token,
@ -728,58 +762,148 @@ HInstruction* HGraphBuilder::IfBuilder::BeginIf(
compare->set_observed_input_representation(input_representation, compare->set_observed_input_representation(input_representation,
input_representation); input_representation);
compare->ChangeRepresentation(input_representation); compare->ChangeRepresentation(input_representation);
compare->SetSuccessorAt(0, first_true_block_); AddCompare(compare);
compare->SetSuccessorAt(1, first_false_block_);
builder_->current_block()->Finish(compare);
builder_->set_current_block(first_true_block_);
return compare; return compare;
} }
HInstruction* HGraphBuilder::IfBuilder::BeginIfObjectsEqual( HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
HValue* left, Handle<Map> map) {
HValue* right) { HCompareMap* compare =
HCompareObjectEqAndBranch* compare = new(zone()) HCompareMap(left, map,
new(zone()) HCompareObjectEqAndBranch(left, right); first_true_block_, first_false_block_);
compare->SetSuccessorAt(0, first_true_block_); AddCompare(compare);
compare->SetSuccessorAt(1, first_false_block_);
builder_->current_block()->Finish(compare);
builder_->set_current_block(first_true_block_);
return compare; return compare;
} }
HInstruction* HGraphBuilder::IfBuilder::BeginIfMapEquals(HValue* value, void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
Handle<Map> map) { if (split_edge_merge_block_ != NULL) {
HCompareMap* compare = new(zone()) HEnvironment* env = first_false_block_->last_environment();
HCompareMap(value, map, first_true_block_, first_false_block_); HBasicBlock* split_edge =
builder_->CreateBasicBlock(env->Copy());
if (did_or_) {
compare->SetSuccessorAt(0, split_edge);
compare->SetSuccessorAt(1, first_false_block_);
} else {
compare->SetSuccessorAt(0, first_true_block_);
compare->SetSuccessorAt(1, split_edge);
}
split_edge->GotoNoSimulate(split_edge_merge_block_);
} else {
compare->SetSuccessorAt(0, first_true_block_);
compare->SetSuccessorAt(1, first_false_block_);
}
builder_->current_block()->Finish(compare); builder_->current_block()->Finish(compare);
needs_compare_ = false;
}
void HGraphBuilder::IfBuilder::Or() {
ASSERT(!did_and_);
did_or_ = true;
HEnvironment* env = first_false_block_->last_environment();
if (split_edge_merge_block_ == NULL) {
split_edge_merge_block_ =
builder_->CreateBasicBlock(env->Copy());
first_true_block_->GotoNoSimulate(split_edge_merge_block_);
first_true_block_ = split_edge_merge_block_;
}
builder_->set_current_block(first_false_block_);
first_false_block_ = builder_->CreateBasicBlock(env->Copy());
}
void HGraphBuilder::IfBuilder::And() {
ASSERT(!did_or_);
did_and_ = true;
HEnvironment* env = first_false_block_->last_environment();
if (split_edge_merge_block_ == NULL) {
split_edge_merge_block_ = builder_->CreateBasicBlock(env->Copy());
first_false_block_->GotoNoSimulate(split_edge_merge_block_);
first_false_block_ = split_edge_merge_block_;
}
builder_->set_current_block(first_true_block_);
first_true_block_ = builder_->CreateBasicBlock(env->Copy());
}
void HGraphBuilder::IfBuilder::CaptureContinuation(
HIfContinuation* continuation) {
ASSERT(!finished_);
ASSERT(!captured_);
HBasicBlock* true_block = last_true_block_ == NULL
? first_true_block_
: last_true_block_;
HBasicBlock* false_block =
did_else_ ? builder_->current_block() : first_false_block_;
continuation->Capture(true_block, false_block, position_);
captured_ = true;
End();
}
void HGraphBuilder::IfBuilder::Then() {
ASSERT(!captured_);
ASSERT(!finished_);
did_then_ = true;
if (needs_compare_) {
// Handle if's without any expressions, they jump directly to the "else"
// branch.
builder_->current_block()->GotoNoSimulate(first_false_block_);
first_true_block_ = NULL;
}
builder_->set_current_block(first_true_block_); builder_->set_current_block(first_true_block_);
return compare;
} }
void HGraphBuilder::IfBuilder::BeginElse() { void HGraphBuilder::IfBuilder::Else() {
ASSERT(did_then_);
ASSERT(!captured_);
ASSERT(!finished_);
last_true_block_ = builder_->current_block(); last_true_block_ = builder_->current_block();
ASSERT(!last_true_block_->IsFinished()); ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished());
builder_->set_current_block(first_false_block_); builder_->set_current_block(first_false_block_);
did_else_ = true; did_else_ = true;
} }
void HGraphBuilder::IfBuilder::Deopt() {
ASSERT(!(did_then_ ^ did_else_));
HBasicBlock* block = builder_->current_block();
block->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
if (did_else_) {
first_false_block_ = NULL;
did_else_ = false;
} else {
first_true_block_ = NULL;
}
}
void HGraphBuilder::IfBuilder::End() { void HGraphBuilder::IfBuilder::End() {
ASSERT(!finished_); if (!captured_) {
if (!did_else_) BeginElse(); ASSERT(did_then_);
ASSERT(!last_true_block_->IsFinished()); if (!did_else_) {
HBasicBlock* last_false_block = builder_->current_block(); last_true_block_ = builder_->current_block();
ASSERT(!last_false_block->IsFinished()); }
HEnvironment* merge_env = if (first_true_block_ == NULL) {
last_true_block_->last_environment()->CopyWithoutHistory(); // Deopt on true. Nothing to do, just continue the else block.
merge_block_ = builder_->CreateBasicBlock(merge_env, id_); } else if (first_false_block_ == NULL) {
last_true_block_->Goto(merge_block_); builder_->set_current_block(last_true_block_);
last_false_block->Goto(merge_block_); } else {
merge_block_->SetJoinId(id_); HEnvironment* merge_env = last_true_block_->last_environment()->Copy();
builder_->set_current_block(merge_block_); merge_block_ = builder_->CreateBasicBlock(merge_env);
ASSERT(!finished_);
if (!did_else_) Else();
ASSERT(!last_true_block_->IsFinished());
HBasicBlock* last_false_block = builder_->current_block();
ASSERT(!last_false_block->IsFinished());
last_true_block_->GotoNoSimulate(merge_block_);
last_false_block->GotoNoSimulate(merge_block_);
builder_->set_current_block(merge_block_);
}
}
finished_ = true; finished_ = true;
} }
@ -790,9 +914,8 @@ HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
: builder_(builder), : builder_(builder),
context_(context), context_(context),
direction_(direction), direction_(direction),
id_(builder->current_block()->last_environment()->previous_ast_id()),
finished_(false) { finished_(false) {
header_block_ = builder->CreateLoopHeaderBlock(id_); header_block_ = builder->CreateLoopHeaderBlock();
body_block_ = NULL; body_block_ = NULL;
exit_block_ = NULL; exit_block_ = NULL;
} }
@ -809,12 +932,12 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody(
phi_->AddInput(initial); phi_->AddInput(initial);
phi_->ChangeRepresentation(Representation::Integer32()); phi_->ChangeRepresentation(Representation::Integer32());
env->Push(initial); env->Push(initial);
builder_->current_block()->Goto(header_block_); builder_->current_block()->GotoNoSimulate(header_block_);
HEnvironment* body_env = env->Copy(); HEnvironment* body_env = env->Copy();
HEnvironment* exit_env = env->Copy(); HEnvironment* exit_env = env->Copy();
body_block_ = builder_->CreateBasicBlock(body_env, id_); body_block_ = builder_->CreateBasicBlock(body_env);
exit_block_ = builder_->CreateBasicBlock(exit_env, id_); exit_block_ = builder_->CreateBasicBlock(exit_env);
// Remove the phi from the expression stack // Remove the phi from the expression stack
body_env->Pop(); body_env->Pop();
@ -863,9 +986,8 @@ void HGraphBuilder::LoopBuilder::EndBody() {
// Push the new increment value on the expression stack to merge into the phi. // Push the new increment value on the expression stack to merge into the phi.
builder_->environment()->Push(increment_); builder_->environment()->Push(increment_);
builder_->current_block()->Goto(header_block_); builder_->current_block()->GotoNoSimulate(header_block_);
header_block_->loop_information()->RegisterBackEdge(body_block_); header_block_->loop_information()->RegisterBackEdge(body_block_);
header_block_->SetJoinId(id_);
builder_->set_current_block(exit_block_); builder_->set_current_block(exit_block_);
// Pop the phi from the expression stack // Pop the phi from the expression stack
@ -900,7 +1022,6 @@ void HGraphBuilder::AddSimulate(BailoutId id,
ASSERT(current_block() != NULL); ASSERT(current_block() != NULL);
ASSERT(no_side_effects_scope_count_ == 0); ASSERT(no_side_effects_scope_count_ == 0);
current_block()->AddSimulate(id, removable); current_block()->AddSimulate(id, removable);
environment()->set_previous_ast_id(id);
} }
@ -935,23 +1056,37 @@ HReturn* HGraphBuilder::AddReturn(HValue* value) {
} }
HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env, HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
BailoutId previous_ast_id) {
HBasicBlock* b = graph()->CreateBasicBlock(); HBasicBlock* b = graph()->CreateBasicBlock();
b->SetInitialEnvironment(env, previous_ast_id); b->SetInitialEnvironment(env);
return b; return b;
} }
HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock(BailoutId previous_ast_id) { HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
HBasicBlock* header = graph()->CreateBasicBlock(); HBasicBlock* header = graph()->CreateBasicBlock();
HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
header->SetInitialEnvironment(entry_env, previous_ast_id); header->SetInitialEnvironment(entry_env);
header->AttachLoopInformation(); header->AttachLoopInformation();
return header; return header;
} }
HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) {
HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj);
AddInstruction(check);
return check;
}
HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
Handle<Map> map) {
HCheckMaps* check = new(zone()) HCheckMaps(obj, map, zone());
AddInstruction(check);
return check;
}
HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
HValue* external_elements, HValue* external_elements,
HValue* checked_key, HValue* checked_key,
@ -1049,14 +1184,16 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
Zone* zone = this->zone(); Zone* zone = this->zone();
IfBuilder length_checker(this); IfBuilder length_checker(this);
length_checker.BeginIf(length, key, Token::EQ); length_checker.IfCompare(length, key, Token::EQ);
length_checker.Then();
HValue* current_capacity = HValue* current_capacity =
AddInstruction(new(zone) HFixedArrayBaseLength(elements)); AddInstruction(new(zone) HFixedArrayBaseLength(elements));
IfBuilder capacity_checker(this); IfBuilder capacity_checker(this);
capacity_checker.BeginIf(length, current_capacity, Token::EQ); capacity_checker.IfCompare(length, current_capacity, Token::EQ);
capacity_checker.Then();
HValue* context = environment()->LookupContext(); HValue* context = environment()->LookupContext();
@ -1068,7 +1205,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
new_capacity); new_capacity);
environment()->Push(new_elements); environment()->Push(new_elements);
capacity_checker.BeginElse(); capacity_checker.Else();
environment()->Push(elements); environment()->Push(elements);
capacity_checker.End(); capacity_checker.End();
@ -1088,7 +1225,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
length_store->SetGVNFlag(kChangesArrayLengths); length_store->SetGVNFlag(kChangesArrayLengths);
} }
length_checker.BeginElse(); length_checker.Else();
AddBoundsCheck(key, length, ALLOW_SMI_KEY); AddBoundsCheck(key, length, ALLOW_SMI_KEY);
environment()->Push(elements); environment()->Push(elements);
@ -1108,19 +1245,19 @@ HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object,
IfBuilder cow_checker(this); IfBuilder cow_checker(this);
cow_checker.BeginIfMapEquals(elements, cow_checker.IfCompareMap(elements,
Handle<Map>(heap->fixed_cow_array_map())); Handle<Map>(heap->fixed_cow_array_map()));
cow_checker.Then();
HValue* capacity = HValue* capacity =
AddInstruction(new(zone) HFixedArrayBaseLength(elements)); AddInstruction(new(zone) HFixedArrayBaseLength(elements));
HValue* new_elements = BuildGrowElementsCapacity(object, elements, HValue* new_elements = BuildGrowElementsCapacity(object, elements,
kind, length, kind, length, capacity);
capacity);
environment()->Push(new_elements); environment()->Push(new_elements);
cow_checker.BeginElse(); cow_checker.Else();
environment()->Push(elements); environment()->Push(elements);
@ -1175,11 +1312,13 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
HValue* checked_key = NULL; HValue* checked_key = NULL;
if (IsExternalArrayElementsKind(elements_kind)) { if (IsExternalArrayElementsKind(elements_kind)) {
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
NoObservableSideEffectsScope no_effects(this);
HLoadExternalArrayPointer* external_elements = HLoadExternalArrayPointer* external_elements =
new(zone) HLoadExternalArrayPointer(elements); new(zone) HLoadExternalArrayPointer(elements);
AddInstruction(external_elements); AddInstruction(external_elements);
IfBuilder length_checker(this); IfBuilder length_checker(this);
length_checker.BeginIf(key, length, Token::LT); length_checker.IfCompare(key, length, Token::LT);
length_checker.Then();
CheckBuilder negative_checker(this); CheckBuilder negative_checker(this);
HValue* bounds_check = negative_checker.CheckIntegerCompare( HValue* bounds_check = negative_checker.CheckIntegerCompare(
key, graph()->GetConstant0(), Token::GTE); key, graph()->GetConstant0(), Token::GTE);
@ -1216,7 +1355,11 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
elements = BuildCheckForCapacityGrow(object, elements, elements_kind, elements = BuildCheckForCapacityGrow(object, elements, elements_kind,
length, key, is_js_array); length, key, is_js_array);
checked_key = key; if (!key->type().IsSmi()) {
checked_key = AddInstruction(new(zone) HCheckSmiOrInt32(key));
} else {
checked_key = key;
}
} else { } else {
checked_key = AddBoundsCheck( checked_key = AddBoundsCheck(
key, length, ALLOW_SMI_KEY, checked_index_representation); key, length, ALLOW_SMI_KEY, checked_index_representation);
@ -1307,8 +1450,7 @@ void HGraphBuilder::BuildInitializeElements(HValue* elements,
HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
ElementsKind kind, ElementsKind kind,
HValue* capacity) { HValue* capacity) {
HValue* new_elements = HValue* new_elements = BuildAllocateElements(context, kind, capacity);
BuildAllocateElements(context, kind, capacity);
BuildInitializeElements(new_elements, kind, capacity); BuildInitializeElements(new_elements, kind, capacity);
return new_elements; return new_elements;
} }
@ -1684,9 +1826,9 @@ HGraph::HGraph(CompilationInfo* info)
start_environment_ = start_environment_ =
new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
} }
start_environment_->set_ast_id(BailoutId::FunctionEntry());
entry_block_ = CreateBasicBlock(); entry_block_ = CreateBasicBlock();
entry_block_->SetInitialEnvironment(start_environment_, entry_block_->SetInitialEnvironment(start_environment_);
BailoutId::FunctionEntry());
} }
@ -3839,8 +3981,8 @@ bool Uint32Analysis::CheckPhiOperands(HPhi* phi) {
HValue* operand = phi->OperandAt(j); HValue* operand = phi->OperandAt(j);
if (!operand->CheckFlag(HInstruction::kUint32)) { if (!operand->CheckFlag(HInstruction::kUint32)) {
// Lazyly mark constants that fit into uint32 range with kUint32 flag. // Lazyly mark constants that fit into uint32 range with kUint32 flag.
if (operand->IsConstant() && if (operand->IsInteger32Constant() &&
HConstant::cast(operand)->IsUint32()) { operand->GetInteger32Constant() >= 0) {
operand->SetFlag(HInstruction::kUint32); operand->SetFlag(HInstruction::kUint32);
continue; continue;
} }
@ -4099,6 +4241,22 @@ void EffectContext::ReturnControl(HControlInstruction* instr,
} }
void EffectContext::ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id) {
HBasicBlock* true_branch = NULL;
HBasicBlock* false_branch = NULL;
continuation->Continue(&true_branch, &false_branch, NULL);
if (!continuation->IsTrueReachable()) {
owner()->set_current_block(false_branch);
} else if (!continuation->IsFalseReachable()) {
owner()->set_current_block(true_branch);
} else {
HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id);
owner()->set_current_block(join);
}
}
void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->IsControlInstruction()); ASSERT(!instr->IsControlInstruction());
if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
@ -4132,6 +4290,29 @@ void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
} }
void ValueContext::ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id) {
HBasicBlock* materialize_true = NULL;
HBasicBlock* materialize_false = NULL;
continuation->Continue(&materialize_true, &materialize_false, NULL);
if (continuation->IsTrueReachable()) {
owner()->set_current_block(materialize_true);
owner()->Push(owner()->graph()->GetConstantTrue());
owner()->set_current_block(materialize_true);
}
if (continuation->IsFalseReachable()) {
owner()->set_current_block(materialize_false);
owner()->Push(owner()->graph()->GetConstantFalse());
owner()->set_current_block(materialize_false);
}
if (continuation->TrueAndFalseReachable()) {
HBasicBlock* join =
owner()->CreateJoin(materialize_true, materialize_false, ast_id);
owner()->set_current_block(join);
}
}
void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->IsControlInstruction()); ASSERT(!instr->IsControlInstruction());
HOptimizedGraphBuilder* builder = owner(); HOptimizedGraphBuilder* builder = owner();
@ -4160,6 +4341,21 @@ void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
} }
void TestContext::ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id) {
HBasicBlock* true_branch = NULL;
HBasicBlock* false_branch = NULL;
continuation->Continue(&true_branch, &false_branch, NULL);
if (continuation->IsTrueReachable()) {
true_branch->Goto(if_true(), owner()->function_state());
}
if (continuation->IsFalseReachable()) {
false_branch->Goto(if_false(), owner()->function_state());
}
owner()->set_current_block(NULL);
}
void TestContext::BuildBranch(HValue* value) { void TestContext::BuildBranch(HValue* value) {
// We expect the graph to be in edge-split form: there is no edge that // We expect the graph to be in edge-split form: there is no edge that
// connects a branch node to a join node. We conservatively ensure that // connects a branch node to a join node. We conservatively ensure that
@ -4296,8 +4492,7 @@ bool HOptimizedGraphBuilder::BuildGraph() {
// values (but not instructions), present in the initial environment and // values (but not instructions), present in the initial environment and
// not replayed by the Lithium translation. // not replayed by the Lithium translation.
HEnvironment* initial_env = environment()->CopyWithoutHistory(); HEnvironment* initial_env = environment()->CopyWithoutHistory();
HBasicBlock* body_entry = CreateBasicBlock(initial_env, HBasicBlock* body_entry = CreateBasicBlock(initial_env);
BailoutId::FunctionEntry());
current_block()->Goto(body_entry); current_block()->Goto(body_entry);
body_entry->SetJoinId(BailoutId::FunctionEntry()); body_entry->SetJoinId(BailoutId::FunctionEntry());
set_current_block(body_entry); set_current_block(body_entry);
@ -5541,7 +5736,7 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
ASSERT(current_block()->HasPredecessor()); ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL); ASSERT(current_block() != NULL);
bool osr_entry = PreProcessOsrEntry(stmt); bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry); current_block()->Goto(loop_entry);
set_current_block(loop_entry); set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
@ -5584,7 +5779,7 @@ void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
ASSERT(current_block()->HasPredecessor()); ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL); ASSERT(current_block() != NULL);
bool osr_entry = PreProcessOsrEntry(stmt); bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry); current_block()->Goto(loop_entry);
set_current_block(loop_entry); set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
@ -5631,7 +5826,7 @@ void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
} }
ASSERT(current_block() != NULL); ASSERT(current_block() != NULL);
bool osr_entry = PreProcessOsrEntry(stmt); bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry); current_block()->Goto(loop_entry);
set_current_block(loop_entry); set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
@ -5726,7 +5921,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
HForInCacheArray::cast(index_cache)); HForInCacheArray::cast(index_cache));
bool osr_entry = PreProcessOsrEntry(stmt); bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry); current_block()->Goto(loop_entry);
set_current_block(loop_entry); set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
@ -6804,7 +6999,6 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
true, // is_store true, // is_store
&has_side_effects); &has_side_effects);
Push(value); Push(value);
ASSERT(has_side_effects); // Stores always have side effects.
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
return ast_context()->ReturnValue(Pop()); return ast_context()->ReturnValue(Pop());
} }
@ -8279,7 +8473,6 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
AddSimulate(return_id); AddSimulate(return_id);
current_block()->UpdateEnvironment(inner_env); current_block()->UpdateEnvironment(inner_env);
inner_env->set_previous_ast_id(BailoutId::FunctionEntry());
ZoneList<HValue*>* arguments_values = NULL; ZoneList<HValue*>* arguments_values = NULL;
// If the function uses arguments copy current arguments values // If the function uses arguments copy current arguments values
@ -8547,6 +8740,18 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
return true; return true;
} }
break; break;
case kStringFromCharCode:
if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
HValue* argument = Pop();
HValue* context = environment()->LookupContext();
Drop(1); // Receiver.
HInstruction* result =
HStringCharFromCode::New(zone(), context, argument);
ast_context()->ReturnInstruction(result, expr->id());
return true;
}
break;
case kMathExp: case kMathExp:
if (!FLAG_fast_math) break; if (!FLAG_fast_math) break;
// Fall through if FLAG_fast_math. // Fall through if FLAG_fast_math.
@ -8600,9 +8805,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
} else if (exponent == 2.0) { } else if (exponent == 2.0) {
result = HMul::New(zone(), context, left, left); result = HMul::New(zone(), context, left, left);
} }
} else if (right->IsConstant() && } else if (right->EqualsInteger32Constant(2)) {
HConstant::cast(right)->HasInteger32Value() &&
HConstant::cast(right)->Integer32Value() == 2) {
result = HMul::New(zone(), context, left, left); result = HMul::New(zone(), context, left, left);
} }
@ -9160,7 +9363,6 @@ void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
case Token::DELETE: return VisitDelete(expr); case Token::DELETE: return VisitDelete(expr);
case Token::VOID: return VisitVoid(expr); case Token::VOID: return VisitVoid(expr);
case Token::TYPEOF: return VisitTypeof(expr); case Token::TYPEOF: return VisitTypeof(expr);
case Token::ADD: return VisitAdd(expr);
case Token::SUB: return VisitSub(expr); case Token::SUB: return VisitSub(expr);
case Token::BIT_NOT: return VisitBitNot(expr); case Token::BIT_NOT: return VisitBitNot(expr);
case Token::NOT: return VisitNot(expr); case Token::NOT: return VisitNot(expr);
@ -9218,21 +9420,6 @@ void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) {
} }
void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) {
CHECK_ALIVE(VisitForValue(expr->expression()));
HValue* value = Pop();
HValue* context = environment()->LookupContext();
HInstruction* instr =
HMul::New(zone(), context, value, graph()->GetConstant1());
if (instr->IsBinaryOperation()) {
// Since we don't have type feedback, we must be cautious/pessimistic.
HBinaryOperation::cast(instr)->set_observed_input_representation(
Representation::Tagged(), Representation::Tagged());
}
return ast_context()->ReturnInstruction(instr, expr->id());
}
void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
CHECK_ALIVE(VisitForValue(expr->expression())); CHECK_ALIVE(VisitForValue(expr->expression()));
HValue* value = Pop(); HValue* value = Pop();
@ -11033,7 +11220,6 @@ HEnvironment::HEnvironment(HEnvironment* outer,
pop_count_(0), pop_count_(0),
push_count_(0), push_count_(0),
ast_id_(BailoutId::None()), ast_id_(BailoutId::None()),
previous_ast_id_(BailoutId::None()),
zone_(zone) { zone_(zone) {
Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0);
} }
@ -11050,7 +11236,6 @@ HEnvironment::HEnvironment(Zone* zone, int parameter_count)
pop_count_(0), pop_count_(0),
push_count_(0), push_count_(0),
ast_id_(BailoutId::None()), ast_id_(BailoutId::None()),
previous_ast_id_(BailoutId::None()),
zone_(zone) { zone_(zone) {
Initialize(parameter_count, 0, 0); Initialize(parameter_count, 0, 0);
} }
@ -11067,7 +11252,6 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
pop_count_(0), pop_count_(0),
push_count_(0), push_count_(0),
ast_id_(other->ast_id()), ast_id_(other->ast_id()),
previous_ast_id_(BailoutId::None()),
zone_(zone) { zone_(zone) {
Initialize(other); Initialize(other);
} }
@ -11088,7 +11272,6 @@ HEnvironment::HEnvironment(HEnvironment* outer,
pop_count_(0), pop_count_(0),
push_count_(0), push_count_(0),
ast_id_(BailoutId::None()), ast_id_(BailoutId::None()),
previous_ast_id_(BailoutId::None()),
zone_(zone) { zone_(zone) {
} }

185
deps/v8/src/hydrogen.h

@ -108,7 +108,7 @@ class HBasicBlock: public ZoneObject {
bool Dominates(HBasicBlock* other) const; bool Dominates(HBasicBlock* other) const;
int LoopNestingDepth() const; int LoopNestingDepth() const;
void SetInitialEnvironment(HEnvironment* env, BailoutId previous_id); void SetInitialEnvironment(HEnvironment* env);
void ClearEnvironment() { last_environment_ = NULL; } void ClearEnvironment() { last_environment_ = NULL; }
bool HasEnvironment() const { return last_environment_ != NULL; } bool HasEnvironment() const { return last_environment_ != NULL; }
void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
@ -125,7 +125,12 @@ class HBasicBlock: public ZoneObject {
void Finish(HControlInstruction* last); void Finish(HControlInstruction* last);
void FinishExit(HControlInstruction* instruction); void FinishExit(HControlInstruction* instruction);
void Goto(HBasicBlock* block, FunctionState* state = NULL); void Goto(HBasicBlock* block,
FunctionState* state = NULL,
bool add_simulate = true);
void GotoNoSimulate(HBasicBlock* block) {
Goto(block, NULL, false);
}
int PredecessorIndexOf(HBasicBlock* predecessor) const; int PredecessorIndexOf(HBasicBlock* predecessor) const;
void AddSimulate(BailoutId ast_id, void AddSimulate(BailoutId ast_id,
@ -484,8 +489,6 @@ class HEnvironment: public ZoneObject {
BailoutId ast_id() const { return ast_id_; } BailoutId ast_id() const { return ast_id_; }
void set_ast_id(BailoutId id) { ast_id_ = id; } void set_ast_id(BailoutId id) { ast_id_ = id; }
BailoutId previous_ast_id() const { return previous_ast_id_; }
void set_previous_ast_id(BailoutId id) { previous_ast_id_ = id; }
HEnterInlined* entry() const { return entry_; } HEnterInlined* entry() const { return entry_; }
void set_entry(HEnterInlined* entry) { entry_ = entry; } void set_entry(HEnterInlined* entry) { entry_ = entry; }
@ -647,7 +650,6 @@ class HEnvironment: public ZoneObject {
int pop_count_; int pop_count_;
int push_count_; int push_count_;
BailoutId ast_id_; BailoutId ast_id_;
BailoutId previous_ast_id_;
Zone* zone_; Zone* zone_;
}; };
@ -678,6 +680,9 @@ enum ArgumentsAllowedFlag {
ARGUMENTS_ALLOWED ARGUMENTS_ALLOWED
}; };
class HIfContinuation;
// This class is not BASE_EMBEDDED because our inlining implementation uses // This class is not BASE_EMBEDDED because our inlining implementation uses
// new and delete. // new and delete.
class AstContext { class AstContext {
@ -703,6 +708,13 @@ class AstContext {
// expressions. // expressions.
virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0; virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
// Finishes the current basic block and materialize a boolean for
// value context, nothing for effect, generate a branch for test context.
// Call this function in tail position in the Visit functions for
// expressions that use an IfBuilder.
virtual void ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id) = 0;
void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; } void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
bool is_for_typeof() { return for_typeof_; } bool is_for_typeof() { return for_typeof_; }
@ -738,6 +750,8 @@ class EffectContext: public AstContext {
virtual void ReturnValue(HValue* value); virtual void ReturnValue(HValue* value);
virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id); virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id); virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
virtual void ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id);
}; };
@ -751,6 +765,8 @@ class ValueContext: public AstContext {
virtual void ReturnValue(HValue* value); virtual void ReturnValue(HValue* value);
virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id); virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id); virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
virtual void ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id);
bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; } bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
@ -776,6 +792,8 @@ class TestContext: public AstContext {
virtual void ReturnValue(HValue* value); virtual void ReturnValue(HValue* value);
virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id); virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id); virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
virtual void ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id);
static TestContext* cast(AstContext* context) { static TestContext* cast(AstContext* context) {
ASSERT(context->IsTest()); ASSERT(context->IsTest());
@ -863,6 +881,45 @@ class FunctionState {
}; };
class HIfContinuation {
public:
HIfContinuation() { continuation_captured_ = false; }
~HIfContinuation() { ASSERT(!continuation_captured_); }
void Capture(HBasicBlock* true_branch,
HBasicBlock* false_branch,
int position) {
ASSERT(!continuation_captured_);
ASSERT(true_branch != NULL || false_branch != NULL);
true_branch_ = true_branch;
false_branch_ = false_branch;
position_ = position;
continuation_captured_ = true;
}
void Continue(HBasicBlock** true_branch,
HBasicBlock** false_branch,
int* position) {
ASSERT(continuation_captured_);
*true_branch = true_branch_;
*false_branch = false_branch_;
if (position != NULL) *position = position_;
continuation_captured_ = false;
}
bool IsTrueReachable() { return true_branch_ != NULL; }
bool IsFalseReachable() { return false_branch_ != NULL; }
bool TrueAndFalseReachable() {
return IsTrueReachable() || IsFalseReachable();
}
bool continuation_captured_;
HBasicBlock* true_branch_;
HBasicBlock* false_branch_;
int position_;
};
class HGraphBuilder { class HGraphBuilder {
public: public:
explicit HGraphBuilder(CompilationInfo* info) explicit HGraphBuilder(CompilationInfo* info)
@ -906,9 +963,11 @@ class HGraphBuilder {
protected: protected:
virtual bool BuildGraph() = 0; virtual bool BuildGraph() = 0;
HBasicBlock* CreateBasicBlock(HEnvironment* envy, HBasicBlock* CreateBasicBlock(HEnvironment* env);
BailoutId previous_ast_id); HBasicBlock* CreateLoopHeaderBlock();
HBasicBlock* CreateLoopHeaderBlock(BailoutId previous_ast_id);
HValue* BuildCheckNonSmi(HValue* object);
HValue* BuildCheckMap(HValue* obj, Handle<Map> map);
// Building common constructs // Building common constructs
HInstruction* BuildExternalArrayElementAccess( HInstruction* BuildExternalArrayElementAccess(
@ -973,37 +1032,127 @@ class HGraphBuilder {
bool finished_; bool finished_;
HBasicBlock* failure_block_; HBasicBlock* failure_block_;
HBasicBlock* merge_block_; HBasicBlock* merge_block_;
BailoutId id_;
}; };
class IfBuilder { class IfBuilder {
public: public:
explicit IfBuilder(HGraphBuilder* builder); explicit IfBuilder(HGraphBuilder* builder,
int position = RelocInfo::kNoPosition);
IfBuilder(HGraphBuilder* builder,
HIfContinuation* continuation);
~IfBuilder() { ~IfBuilder() {
if (!finished_) End(); if (!finished_) End();
} }
HInstruction* BeginIf( HInstruction* IfCompare(
HValue* left, HValue* left,
HValue* right, HValue* right,
Token::Value token, Token::Value token,
Representation input_representation = Representation::Integer32()); Representation input_representation = Representation::Integer32());
HInstruction* BeginIfObjectsEqual(HValue* left, HValue* right);
HInstruction* BeginIfMapEquals(HValue* value, Handle<Map> map); HInstruction* IfCompareMap(HValue* left, Handle<Map> map);
void BeginElse();
template<class Condition>
HInstruction* If(HValue *p) {
HControlInstruction* compare = new(zone()) Condition(p);
AddCompare(compare);
return compare;
}
template<class Condition, class P2>
HInstruction* If(HValue* p1, P2 p2) {
HControlInstruction* compare = new(zone()) Condition(p1, p2);
AddCompare(compare);
return compare;
}
template<class Condition>
HInstruction* OrIfCompare(
HValue* p1,
HValue* p2,
Token::Value token,
Representation input_representation = Representation::Integer32()) {
Or();
return IfCompare(p1, p2, token, input_representation);
}
HInstruction* OrIfCompareMap(HValue* left, Handle<Map> map) {
Or();
return IfCompareMap(left, map);
}
template<class Condition>
HInstruction* OrIf(HValue *p) {
Or();
return If<Condition>(p);
}
template<class Condition, class P2>
HInstruction* OrIf(HValue* p1, P2 p2) {
Or();
return If<Condition>(p1, p2);
}
template<class Condition>
HInstruction* AndIfCompare(
HValue* p1,
HValue* p2,
Token::Value token,
Representation input_representation = Representation::Integer32()) {
And();
return IfCompare(p1, p2, token, input_representation);
}
HInstruction* AndIfCompareMap(HValue* left, Handle<Map> map) {
And();
return IfCompareMap(left, map);
}
template<class Condition>
HInstruction* AndIf(HValue *p) {
And();
return If<Condition>(p);
}
template<class Condition, class P2>
HInstruction* AndIf(HValue* p1, P2 p2) {
And();
return If<Condition>(p1, p2);
}
void Or();
void And();
void CaptureContinuation(HIfContinuation* continuation);
void Then();
void Else();
void End(); void End();
void Deopt();
private: private:
void AddCompare(HControlInstruction* compare);
Zone* zone() { return builder_->zone(); } Zone* zone() { return builder_->zone(); }
HGraphBuilder* builder_; HGraphBuilder* builder_;
bool finished_; int position_;
bool did_else_; bool finished_ : 1;
bool did_then_ : 1;
bool did_else_ : 1;
bool deopt_then_ : 1;
bool deopt_else_ : 1;
bool did_and_ : 1;
bool did_or_ : 1;
bool captured_ : 1;
bool needs_compare_ : 1;
HBasicBlock* first_true_block_; HBasicBlock* first_true_block_;
HBasicBlock* last_true_block_; HBasicBlock* last_true_block_;
HBasicBlock* first_false_block_; HBasicBlock* first_false_block_;
HBasicBlock* split_edge_merge_block_;
HBasicBlock* merge_block_; HBasicBlock* merge_block_;
BailoutId id_;
}; };
class LoopBuilder { class LoopBuilder {
@ -1040,7 +1189,6 @@ class HGraphBuilder {
HBasicBlock* body_block_; HBasicBlock* body_block_;
HBasicBlock* exit_block_; HBasicBlock* exit_block_;
Direction direction_; Direction direction_;
BailoutId id_;
bool finished_; bool finished_;
}; };
@ -1267,7 +1415,6 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
void VisitDelete(UnaryOperation* expr); void VisitDelete(UnaryOperation* expr);
void VisitVoid(UnaryOperation* expr); void VisitVoid(UnaryOperation* expr);
void VisitTypeof(UnaryOperation* expr); void VisitTypeof(UnaryOperation* expr);
void VisitAdd(UnaryOperation* expr);
void VisitSub(UnaryOperation* expr); void VisitSub(UnaryOperation* expr);
void VisitBitNot(UnaryOperation* expr); void VisitBitNot(UnaryOperation* expr);
void VisitNot(UnaryOperation* expr); void VisitNot(UnaryOperation* expr);

1
deps/v8/src/ia32/code-stubs-ia32.cc

@ -30,7 +30,6 @@
#if defined(V8_TARGET_ARCH_IA32) #if defined(V8_TARGET_ARCH_IA32)
#include "bootstrapper.h" #include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h" #include "code-stubs.h"
#include "isolate.h" #include "isolate.h"
#include "jsregexp.h" #include "jsregexp.h"

2
deps/v8/src/ia32/code-stubs-ia32.h

@ -144,7 +144,7 @@ class UnaryOpStub: public PlatformCodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::UNARY_OP_IC; } virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() { virtual InlineCacheState GetICState() {
return UnaryOpIC::ToState(operand_type_); return UnaryOpIC::ToState(operand_type_);

12
deps/v8/src/ia32/full-codegen-ia32.cc

@ -3967,18 +3967,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
case Token::ADD: {
Comment cmt(masm_, "[ UnaryOperation (ADD)");
VisitForAccumulatorValue(expr->expression());
Label no_conversion;
__ JumpIfSmi(result_register(), &no_conversion);
ToNumberStub convert_stub;
__ CallStub(&convert_stub);
__ bind(&no_conversion);
context()->Plug(result_register());
break;
}
case Token::SUB: case Token::SUB:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break; break;

20
deps/v8/src/ia32/lithium-codegen-ia32.cc

@ -467,7 +467,7 @@ bool LCodeGen::GenerateDeferredCode() {
LDeferredCode* code = deferred_[i]; LDeferredCode* code = deferred_[i];
__ bind(code->entry()); __ bind(code->entry());
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred build frame", Comment(";;; Deferred build frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(!frame_is_built_); ASSERT(!frame_is_built_);
@ -484,7 +484,7 @@ bool LCodeGen::GenerateDeferredCode() {
code->instr()->Mnemonic()); code->instr()->Mnemonic());
code->Generate(); code->Generate();
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred destroy frame", Comment(";;; Deferred destroy frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(frame_is_built_); ASSERT(frame_is_built_);
@ -1126,11 +1126,9 @@ void LCodeGen::RecordPosition(int position) {
void LCodeGen::DoLabel(LLabel* label) { void LCodeGen::DoLabel(LLabel* label) {
if (label->is_loop_header()) { Comment(";;; -------------------- B%d%s --------------------",
Comment(";;; B%d - LOOP entry", label->block_id()); label->block_id(),
} else { label->is_loop_header() ? " (loop header)" : "");
Comment(";;; B%d", label->block_id());
}
__ bind(label->label()); __ bind(label->label());
current_block_ = label->block_id(); current_block_ = label->block_id();
DoGap(label); DoGap(label);
@ -2287,11 +2285,15 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
Operand right = ToOperand(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id()); int true_block = chunk_->LookupDestination(instr->true_block_id());
__ cmp(left, Operand(right)); if (instr->right()->IsConstantOperand()) {
__ cmp(left, ToHandle(LConstantOperand::cast(instr->right())));
} else {
Operand right = ToOperand(instr->right());
__ cmp(left, Operand(right));
}
EmitBranch(true_block, false_block, equal); EmitBranch(true_block, false_block, equal);
} }

5
deps/v8/src/ia32/lithium-codegen-ia32.h

@ -32,9 +32,10 @@
#include "checks.h" #include "checks.h"
#include "deoptimizer.h" #include "deoptimizer.h"
#include "ia32/lithium-gap-resolver-ia32.h"
#include "safepoint-table.h" #include "safepoint-table.h"
#include "scopes.h" #include "scopes.h"
#include "ia32/lithium-gap-resolver-ia32.h" #include "v8utils.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -201,7 +202,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); } int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
void Abort(const char* reason); void Abort(const char* reason);
void Comment(const char* format, ...); void FPRINTF_CHECKING Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }

12
deps/v8/src/ia32/lithium-ia32.cc

@ -884,11 +884,15 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
HEnvironment* last_environment = pred->last_environment(); HEnvironment* last_environment = pred->last_environment();
for (int i = 0; i < block->phis()->length(); ++i) { for (int i = 0; i < block->phis()->length(); ++i) {
HPhi* phi = block->phis()->at(i); HPhi* phi = block->phis()->at(i);
last_environment->SetValueAt(phi->merged_index(), phi); if (phi->merged_index() < last_environment->length()) {
last_environment->SetValueAt(phi->merged_index(), phi);
}
} }
for (int i = 0; i < block->deleted_phis()->length(); ++i) { for (int i = 0; i < block->deleted_phis()->length(); ++i) {
last_environment->SetValueAt(block->deleted_phis()->at(i), if (block->deleted_phis()->at(i) < last_environment->length()) {
graph_->GetConstantUndefined()); last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
} }
block->UpdateEnvironment(last_environment); block->UpdateEnvironment(last_environment);
// Pick up the outgoing argument count of one of the predecessors. // Pick up the outgoing argument count of one of the predecessors.
@ -1693,7 +1697,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
HCompareObjectEqAndBranch* instr) { HCompareObjectEqAndBranch* instr) {
LOperand* left = UseRegisterAtStart(instr->left()); LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseAtStart(instr->right()); LOperand* right = UseOrConstantAtStart(instr->right());
return new(zone()) LCmpObjectEqAndBranch(left, right); return new(zone()) LCmpObjectEqAndBranch(left, right);
} }

4
deps/v8/src/ic.cc

@ -1384,7 +1384,7 @@ MaybeObject* KeyedLoadIC::Load(State state,
} }
return Runtime::GetObjectProperty(isolate(), object, key); return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
} }
@ -1972,7 +1972,7 @@ MaybeObject* KeyedStoreIC::Store(State state,
TRACE_IC("KeyedStoreIC", key, state, target()); TRACE_IC("KeyedStoreIC", key, state, target());
} }
return Runtime::SetObjectProperty( return Runtime::SetObjectPropertyOrFail(
isolate(), object , key, value, NONE, strict_mode); isolate(), object , key, value, NONE, strict_mode);
} }

6
deps/v8/src/lithium.cc

@ -442,7 +442,7 @@ LChunk* LChunk::NewChunk(HGraph* graph) {
} }
Handle<Code> LChunk::Codegen(Code::Kind kind) { Handle<Code> LChunk::Codegen() {
MacroAssembler assembler(info()->isolate(), NULL, 0); MacroAssembler assembler(info()->isolate(), NULL, 0);
LOG_CODE_EVENT(info()->isolate(), LOG_CODE_EVENT(info()->isolate(),
CodeStartLinePosInfoRecordEvent( CodeStartLinePosInfoRecordEvent(
@ -456,11 +456,11 @@ Handle<Code> LChunk::Codegen(Code::Kind kind) {
PrintF("Crankshaft Compiler - "); PrintF("Crankshaft Compiler - ");
} }
CodeGenerator::MakeCodePrologue(info()); CodeGenerator::MakeCodePrologue(info());
Code::Flags flags = Code::ComputeFlags(kind); Code::Flags flags = info()->flags();
Handle<Code> code = Handle<Code> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
generator.FinishCode(code); generator.FinishCode(code);
code->set_is_crankshafted(true);
if (!code.is_null()) { if (!code.is_null()) {
void* jit_handler_data = void* jit_handler_data =
assembler.positions_recorder()->DetachJITHandlerData(); assembler.positions_recorder()->DetachJITHandlerData();

2
deps/v8/src/lithium.h

@ -685,7 +685,7 @@ class LChunk: public ZoneObject {
Zone* zone() const { return info_->zone(); } Zone* zone() const { return info_->zone(); }
Handle<Code> Codegen(Code::Kind kind); Handle<Code> Codegen();
void set_allocated_double_registers(BitVector* allocated_registers); void set_allocated_double_registers(BitVector* allocated_registers);
BitVector* allocated_double_registers() { BitVector* allocated_double_registers() {

1
deps/v8/src/log.cc

@ -1590,7 +1590,6 @@ void Logger::LogCodeObject(Object* object) {
case Code::BINARY_OP_IC: // fall through case Code::BINARY_OP_IC: // fall through
case Code::COMPARE_IC: // fall through case Code::COMPARE_IC: // fall through
case Code::TO_BOOLEAN_IC: // fall through case Code::TO_BOOLEAN_IC: // fall through
case Code::COMPILED_STUB: // fall through
case Code::STUB: case Code::STUB:
description = description =
CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true); CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true);

1
deps/v8/src/macros.py

@ -117,6 +117,7 @@ macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script');
macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments'); macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments');
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global'); macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === '__ArrayBuffer'); macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === '__ArrayBuffer');
macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(arg)); macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(arg));
macro FLOOR(arg) = $floor(arg); macro FLOOR(arg) = $floor(arg);

1
deps/v8/src/mips/code-stubs-mips.cc

@ -30,7 +30,6 @@
#if defined(V8_TARGET_ARCH_MIPS) #if defined(V8_TARGET_ARCH_MIPS)
#include "bootstrapper.h" #include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h" #include "code-stubs.h"
#include "codegen.h" #include "codegen.h"
#include "regexp-macro-assembler.h" #include "regexp-macro-assembler.h"

2
deps/v8/src/mips/code-stubs-mips.h

@ -131,7 +131,7 @@ class UnaryOpStub: public PlatformCodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::UNARY_OP_IC; } virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() { virtual InlineCacheState GetICState() {
return UnaryOpIC::ToState(operand_type_); return UnaryOpIC::ToState(operand_type_);

13
deps/v8/src/mips/full-codegen-mips.cc

@ -3995,19 +3995,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
case Token::ADD: {
Comment cmt(masm_, "[ UnaryOperation (ADD)");
VisitForAccumulatorValue(expr->expression());
Label no_conversion;
__ JumpIfSmi(result_register(), &no_conversion);
__ mov(a0, result_register());
ToNumberStub convert_stub;
__ CallStub(&convert_stub);
__ bind(&no_conversion);
context()->Plug(result_register());
break;
}
case Token::SUB: case Token::SUB:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break; break;

12
deps/v8/src/mips/lithium-codegen-mips.cc

@ -301,7 +301,7 @@ bool LCodeGen::GenerateDeferredCode() {
LDeferredCode* code = deferred_[i]; LDeferredCode* code = deferred_[i];
__ bind(code->entry()); __ bind(code->entry());
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred build frame", Comment(";;; Deferred build frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(!frame_is_built_); ASSERT(!frame_is_built_);
@ -317,7 +317,7 @@ bool LCodeGen::GenerateDeferredCode() {
code->instr()->Mnemonic()); code->instr()->Mnemonic());
code->Generate(); code->Generate();
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred destroy frame", Comment(";;; Deferred destroy frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(frame_is_built_); ASSERT(frame_is_built_);
@ -1024,11 +1024,9 @@ void LCodeGen::RecordPosition(int position) {
void LCodeGen::DoLabel(LLabel* label) { void LCodeGen::DoLabel(LLabel* label) {
if (label->is_loop_header()) { Comment(";;; -------------------- B%d%s --------------------",
Comment(";;; B%d - LOOP entry", label->block_id()); label->block_id(),
} else { label->is_loop_header() ? " (loop header)" : "");
Comment(";;; B%d", label->block_id());
}
__ bind(label->label()); __ bind(label->label());
current_block_ = label->block_id(); current_block_ = label->block_id();
DoGap(label); DoGap(label);

7
deps/v8/src/mips/lithium-codegen-mips.h

@ -28,11 +28,12 @@
#ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_ #ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
#define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_ #define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
#include "mips/lithium-mips.h"
#include "mips/lithium-gap-resolver-mips.h"
#include "deoptimizer.h" #include "deoptimizer.h"
#include "mips/lithium-gap-resolver-mips.h"
#include "mips/lithium-mips.h"
#include "safepoint-table.h" #include "safepoint-table.h"
#include "scopes.h" #include "scopes.h"
#include "v8utils.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -207,7 +208,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); } int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
void Abort(const char* reason); void Abort(const char* reason);
void Comment(const char* format, ...); void FPRINTF_CHECKING Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }

23
deps/v8/src/objects-inl.h

@ -3645,9 +3645,21 @@ int Code::arguments_count() {
} }
inline bool Code::is_crankshafted() {
return IsCrankshaftedField::decode(
READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
}
inline void Code::set_is_crankshafted(bool value) {
int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
int updated = IsCrankshaftedField::update(previous, value);
WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
int Code::major_key() { int Code::major_key() {
ASSERT(kind() == STUB || ASSERT(kind() == STUB ||
kind() == COMPILED_STUB ||
kind() == UNARY_OP_IC || kind() == UNARY_OP_IC ||
kind() == BINARY_OP_IC || kind() == BINARY_OP_IC ||
kind() == COMPARE_IC || kind() == COMPARE_IC ||
@ -3661,7 +3673,6 @@ int Code::major_key() {
void Code::set_major_key(int major) { void Code::set_major_key(int major) {
ASSERT(kind() == STUB || ASSERT(kind() == STUB ||
kind() == COMPILED_STUB ||
kind() == UNARY_OP_IC || kind() == UNARY_OP_IC ||
kind() == BINARY_OP_IC || kind() == BINARY_OP_IC ||
kind() == COMPARE_IC || kind() == COMPARE_IC ||
@ -3774,7 +3785,7 @@ void Code::set_profiler_ticks(int ticks) {
unsigned Code::stack_slots() { unsigned Code::stack_slots() {
ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); ASSERT(is_crankshafted());
return StackSlotsField::decode( return StackSlotsField::decode(
READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
} }
@ -3782,7 +3793,7 @@ unsigned Code::stack_slots() {
void Code::set_stack_slots(unsigned slots) { void Code::set_stack_slots(unsigned slots) {
CHECK(slots <= (1 << kStackSlotsBitCount)); CHECK(slots <= (1 << kStackSlotsBitCount));
ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); ASSERT(is_crankshafted());
int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
int updated = StackSlotsField::update(previous, slots); int updated = StackSlotsField::update(previous, slots);
WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
@ -3790,7 +3801,7 @@ void Code::set_stack_slots(unsigned slots) {
unsigned Code::safepoint_table_offset() { unsigned Code::safepoint_table_offset() {
ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); ASSERT(is_crankshafted());
return SafepointTableOffsetField::decode( return SafepointTableOffsetField::decode(
READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)); READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
} }
@ -3798,7 +3809,7 @@ unsigned Code::safepoint_table_offset() {
void Code::set_safepoint_table_offset(unsigned offset) { void Code::set_safepoint_table_offset(unsigned offset) {
CHECK(offset <= (1 << kSafepointTableOffsetBitCount)); CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); ASSERT(is_crankshafted());
ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize))); ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
int updated = SafepointTableOffsetField::update(previous, offset); int updated = SafepointTableOffsetField::update(previous, offset);

2
deps/v8/src/objects-printer.cc

@ -187,8 +187,10 @@ void HeapObject::HeapObjectPrint(FILE* out) {
break; break;
case JS_ARRAY_BUFFER_TYPE: case JS_ARRAY_BUFFER_TYPE:
JSArrayBuffer::cast(this)->JSArrayBufferPrint(out); JSArrayBuffer::cast(this)->JSArrayBufferPrint(out);
break;
case JS_TYPED_ARRAY_TYPE: case JS_TYPED_ARRAY_TYPE:
JSTypedArray::cast(this)->JSTypedArrayPrint(out); JSTypedArray::cast(this)->JSTypedArrayPrint(out);
break;
#define MAKE_STRUCT_CASE(NAME, Name, name) \ #define MAKE_STRUCT_CASE(NAME, Name, name) \
case NAME##_TYPE: \ case NAME##_TYPE: \
Name::cast(this)->Name##Print(out); \ Name::cast(this)->Name##Print(out); \

3
deps/v8/src/objects.cc

@ -9313,7 +9313,6 @@ const char* Code::Kind2String(Kind kind) {
switch (kind) { switch (kind) {
case FUNCTION: return "FUNCTION"; case FUNCTION: return "FUNCTION";
case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION"; case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
case COMPILED_STUB: return "COMPILED_STUB";
case STUB: return "STUB"; case STUB: return "STUB";
case BUILTIN: return "BUILTIN"; case BUILTIN: return "BUILTIN";
case LOAD_IC: return "LOAD_IC"; case LOAD_IC: return "LOAD_IC";
@ -9613,7 +9612,7 @@ void Code::Disassemble(const char* name, FILE* out) {
} }
PrintF("\n"); PrintF("\n");
if (kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB) { if (is_crankshafted()) {
SafepointTable table(this); SafepointTable table(this);
PrintF(out, "Safepoints (size = %u)\n", table.size()); PrintF(out, "Safepoints (size = %u)\n", table.size());
for (unsigned i = 0; i < table.length(); i++) { for (unsigned i = 0; i < table.length(); i++) {

23
deps/v8/src/objects.h

@ -4327,7 +4327,6 @@ class Code: public HeapObject {
V(FUNCTION) \ V(FUNCTION) \
V(OPTIMIZED_FUNCTION) \ V(OPTIMIZED_FUNCTION) \
V(STUB) \ V(STUB) \
V(COMPILED_STUB) \
V(BUILTIN) \ V(BUILTIN) \
V(LOAD_IC) \ V(LOAD_IC) \
V(KEYED_LOAD_IC) \ V(KEYED_LOAD_IC) \
@ -4470,6 +4469,11 @@ class Code: public HeapObject {
inline int major_key(); inline int major_key();
inline void set_major_key(int value); inline void set_major_key(int value);
// For kind STUB or ICs, tells whether or not a code object was generated by
// the optimizing compiler (but it may not be an optimized function).
bool is_crankshafted();
inline void set_is_crankshafted(bool value);
// For stubs, tells whether they should always exist, so that they can be // For stubs, tells whether they should always exist, so that they can be
// called from other stubs. // called from other stubs.
inline bool is_pregenerated(); inline bool is_pregenerated();
@ -4785,15 +4789,22 @@ class Code: public HeapObject {
kMarkedForDeoptimizationFirstBit, kMarkedForDeoptimizationFirstBit,
kMarkedForDeoptimizationBitCount> {}; // NOLINT kMarkedForDeoptimizationBitCount> {}; // NOLINT
// KindSpecificFlags2 layout (ALL)
static const int kIsCrankshaftedBit = 0;
class IsCrankshaftedField: public BitField<bool,
kIsCrankshaftedBit, 1> {}; // NOLINT
// KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION) // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
static const int kStubMajorKeyFirstBit = 0; static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1;
static const int kSafepointTableOffsetFirstBit = static const int kSafepointTableOffsetFirstBit =
kStubMajorKeyFirstBit + kStubMajorKeyBits; kStubMajorKeyFirstBit + kStubMajorKeyBits;
static const int kSafepointTableOffsetBitCount = 26; static const int kSafepointTableOffsetBitCount = 25;
STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32); STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
STATIC_ASSERT(kSafepointTableOffsetFirstBit + STATIC_ASSERT(kSafepointTableOffsetFirstBit +
kSafepointTableOffsetBitCount <= 32); kSafepointTableOffsetBitCount <= 32);
STATIC_ASSERT(1 + kStubMajorKeyBits +
kSafepointTableOffsetBitCount <= 32);
class SafepointTableOffsetField: public BitField<int, class SafepointTableOffsetField: public BitField<int,
kSafepointTableOffsetFirstBit, kSafepointTableOffsetFirstBit,
@ -4802,8 +4813,10 @@ class Code: public HeapObject {
kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT
// KindSpecificFlags2 layout (FUNCTION) // KindSpecificFlags2 layout (FUNCTION)
class BackEdgeTableOffsetField: public BitField<int, 0, 31> {}; class BackEdgeTableOffsetField: public BitField<int,
class BackEdgesPatchedForOSRField: public BitField<bool, 31, 1> {}; kIsCrankshaftedBit + 1, 29> {}; // NOLINT
class BackEdgesPatchedForOSRField: public BitField<bool,
kIsCrankshaftedBit + 1 + 29, 1> {}; // NOLINT
// Signed field cannot be encoded using the BitField class. // Signed field cannot be encoded using the BitField class.
static const int kArgumentsCountShift = 17; static const int kArgumentsCountShift = 17;

15
deps/v8/src/parser.cc

@ -1872,9 +1872,10 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
const int literals = fun->NumberOfLiterals(); const int literals = fun->NumberOfLiterals();
Handle<Code> code = Handle<Code>(fun->shared()->code()); Handle<Code> code = Handle<Code>(fun->shared()->code());
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
bool is_generator = false;
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
isolate()->factory()->NewSharedFunctionInfo(name, literals, code, isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
Handle<ScopeInfo>(fun->shared()->scope_info())); code, Handle<ScopeInfo>(fun->shared()->scope_info()));
shared->set_construct_stub(*construct_stub); shared->set_construct_stub(*construct_stub);
// Copy the function data to the shared function info. // Copy the function data to the shared function info.
@ -3286,6 +3287,16 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
} }
} }
// Desugar '+foo' into 'foo*1', this enables the collection of type feedback
// without any special stub and the multiplication is removed later in
// Crankshaft's canonicalization pass.
if (op == Token::ADD) {
return factory()->NewBinaryOperation(Token::MUL,
expression,
factory()->NewNumberLiteral(1),
position);
}
return factory()->NewUnaryOperation(op, expression, position); return factory()->NewUnaryOperation(op, expression, position);
} else if (Token::IsCountOp(op)) { } else if (Token::IsCountOp(op)) {

2
deps/v8/src/platform-freebsd.cc

@ -194,9 +194,7 @@ void OS::Abort() {
void OS::DebugBreak() { void OS::DebugBreak() {
#if (defined(__arm__) || defined(__thumb__)) #if (defined(__arm__) || defined(__thumb__))
# if defined(CAN_USE_ARMV5_INSTRUCTIONS)
asm("bkpt 0"); asm("bkpt 0");
# endif
#else #else
asm("int $3"); asm("int $3");
#endif #endif

2
deps/v8/src/platform-linux.cc

@ -419,9 +419,7 @@ void OS::DebugBreak() {
// TODO(lrn): Introduce processor define for runtime system (!= V8_ARCH_x, // TODO(lrn): Introduce processor define for runtime system (!= V8_ARCH_x,
// which is the architecture of generated code). // which is the architecture of generated code).
#if (defined(__arm__) || defined(__thumb__)) #if (defined(__arm__) || defined(__thumb__))
# if defined(CAN_USE_ARMV5_INSTRUCTIONS)
asm("bkpt 0"); asm("bkpt 0");
# endif
#elif defined(__mips__) #elif defined(__mips__)
asm("break"); asm("break");
#elif defined(__native_client__) #elif defined(__native_client__)

17
deps/v8/src/platform-posix.cc

@ -115,26 +115,11 @@ void* OS::GetRandomMmapAddr() {
raw_addr &= V8_UINT64_C(0x3ffffffff000); raw_addr &= V8_UINT64_C(0x3ffffffff000);
#else #else
uint32_t raw_addr = V8::RandomPrivate(isolate); uint32_t raw_addr = V8::RandomPrivate(isolate);
raw_addr &= 0x3ffff000;
# ifdef __sun
// For our Solaris/illumos mmap hint, we pick a random address in the bottom
// half of the top half of the address space (that is, the third quarter).
// Because we do not MAP_FIXED, this will be treated only as a hint -- the
// system will not fail to mmap() because something else happens to already
// be mapped at our random address. We deliberately set the hint high enough
// to get well above the system's break (that is, the heap); Solaris and
// illumos will try the hint and if that fails allocate as if there were
// no hint at all. The high hint prevents the break from getting hemmed in
// at low values, ceding half of the address space to the system heap.
raw_addr += 0x80000000;
# else
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a // The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
// 10.6 and 10.7. // 10.6 and 10.7.
raw_addr &= 0x3ffff000;
raw_addr += 0x20000000; raw_addr += 0x20000000;
# endif
#endif #endif
return reinterpret_cast<void*>(raw_addr); return reinterpret_cast<void*>(raw_addr);
} }

3
deps/v8/src/runtime-profiler.cc

@ -30,6 +30,7 @@
#include "runtime-profiler.h" #include "runtime-profiler.h"
#include "assembler.h" #include "assembler.h"
#include "bootstrapper.h"
#include "code-stubs.h" #include "code-stubs.h"
#include "compilation-cache.h" #include "compilation-cache.h"
#include "deoptimizer.h" #include "deoptimizer.h"
@ -134,7 +135,7 @@ void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) {
PrintF("]\n"); PrintF("]\n");
} }
if (FLAG_parallel_recompilation) { if (FLAG_parallel_recompilation && !isolate_->bootstrapper()->IsActive()) {
ASSERT(!function->IsMarkedForInstallingRecompiledCode()); ASSERT(!function->IsMarkedForInstallingRecompiledCode());
ASSERT(!function->IsInRecompileQueue()); ASSERT(!function->IsInRecompileQueue());
function->MarkForParallelRecompilation(); function->MarkForParallelRecompilation();

38
deps/v8/src/runtime.cc

@ -706,9 +706,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
holder->set_byte_length(byte_length); holder->set_byte_length(byte_length);
v8::Isolate* external_isolate = reinterpret_cast<v8::Isolate*>(isolate); v8::Isolate* external_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Handle<Object> external_holder(*holder); v8::Persistent<v8::Value> weak_handle = v8::Persistent<v8::Value>::New(
Persistent<Object> weak_handle = Persistent<Object>::New( external_isolate, v8::Utils::ToLocal(Handle<Object>::cast(holder)));
external_isolate, external_holder);
weak_handle.MakeWeak(external_isolate, data, ArrayBufferWeakCallback); weak_handle.MakeWeak(external_isolate, data, ArrayBufferWeakCallback);
weak_handle.MarkIndependent(external_isolate); weak_handle.MarkIndependent(external_isolate);
isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
@ -734,8 +733,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
size_t start = static_cast<size_t>(first); size_t start = static_cast<size_t>(first);
size_t target_length = NumberToSize(isolate, target->byte_length()); size_t target_length = NumberToSize(isolate, target->byte_length());
if (target_length == 0) if (target_length == 0) return isolate->heap()->undefined_value();
return isolate->heap()->undefined_value();
ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start); ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start);
uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store()); uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
@ -2417,11 +2415,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
Object* char_code) { Object* char_code) {
uint32_t code; if (char_code->IsNumber()) {
if (char_code->ToArrayIndex(&code)) { return isolate->heap()->LookupSingleCharacterStringFromCode(
if (code <= 0xffff) { NumberToUint32(char_code) & 0xffff);
return isolate->heap()->LookupSingleCharacterStringFromCode(code);
}
} }
return isolate->heap()->empty_string(); return isolate->heap()->empty_string();
} }
@ -4096,6 +4092,13 @@ MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
return isolate->heap()->ToBoolean(object->HasProperty(*name)); return isolate->heap()->ToBoolean(object->HasProperty(*name));
} }
MaybeObject* Runtime::GetObjectPropertyOrFail(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key) {
CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
GetObjectProperty(isolate, object, key));
}
MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
Handle<Object> object, Handle<Object> object,
@ -4380,6 +4383,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
} }
MaybeObject* Runtime::SetObjectPropertyOrFail(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
PropertyAttributes attr,
StrictModeFlag strict_mode) {
CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
SetObjectProperty(isolate, object, key, value, attr, strict_mode));
}
MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object, Handle<Object> object,
Handle<Object> key, Handle<Object> key,
@ -7636,7 +7651,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) {
ASSERT(args.length() == 0); ASSERT(args.length() == 0);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
ASSERT(isolate->heap()->IsAllocationAllowed()); ASSERT(isolate->heap()->IsAllocationAllowed());
ASSERT(deoptimizer->compiled_code_kind() == Code::COMPILED_STUB);
delete deoptimizer; delete deoptimizer;
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
@ -7651,7 +7665,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
ASSERT(isolate->heap()->IsAllocationAllowed()); ASSERT(isolate->heap()->IsAllocationAllowed());
ASSERT(deoptimizer->compiled_code_kind() != Code::COMPILED_STUB); ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION);
// Make sure to materialize objects before causing any allocation. // Make sure to materialize objects before causing any allocation.
JavaScriptFrameIterator it(isolate); JavaScriptFrameIterator it(isolate);

13
deps/v8/src/runtime.h

@ -702,6 +702,14 @@ class Runtime : public AllStatic {
PropertyAttributes attr, PropertyAttributes attr,
StrictModeFlag strict_mode); StrictModeFlag strict_mode);
MUST_USE_RESULT static MaybeObject* SetObjectPropertyOrFail(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
PropertyAttributes attr,
StrictModeFlag strict_mode);
MUST_USE_RESULT static MaybeObject* ForceSetObjectProperty( MUST_USE_RESULT static MaybeObject* ForceSetObjectProperty(
Isolate* isolate, Isolate* isolate,
Handle<JSObject> object, Handle<JSObject> object,
@ -725,6 +733,11 @@ class Runtime : public AllStatic {
Handle<Object> object, Handle<Object> object,
Handle<Object> key); Handle<Object> key);
MUST_USE_RESULT static MaybeObject* GetObjectPropertyOrFail(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key);
// Helper functions used stubs. // Helper functions used stubs.
static void PerformGC(Object* result); static void PerformGC(Object* result);

3
deps/v8/src/safepoint-table.cc

@ -59,8 +59,7 @@ bool SafepointEntry::HasRegisterAt(int reg_index) const {
SafepointTable::SafepointTable(Code* code) { SafepointTable::SafepointTable(Code* code) {
ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION || ASSERT(code->is_crankshafted());
code->kind() == Code::COMPILED_STUB);
code_ = code; code_ = code;
Address header = code->instruction_start() + code->safepoint_table_offset(); Address header = code->instruction_start() + code->safepoint_table_offset();
length_ = Memory::uint32_at(header + kLengthOffset); length_ = Memory::uint32_at(header + kLengthOffset);

1
deps/v8/src/spaces.cc

@ -1807,7 +1807,6 @@ static void ReportCodeKindStatistics() {
CASE(FUNCTION); CASE(FUNCTION);
CASE(OPTIMIZED_FUNCTION); CASE(OPTIMIZED_FUNCTION);
CASE(STUB); CASE(STUB);
CASE(COMPILED_STUB);
CASE(BUILTIN); CASE(BUILTIN);
CASE(LOAD_IC); CASE(LOAD_IC);
CASE(KEYED_LOAD_IC); CASE(KEYED_LOAD_IC);

2
deps/v8/src/version.cc

@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script. // cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3 #define MAJOR_VERSION 3
#define MINOR_VERSION 18 #define MINOR_VERSION 18
#define BUILD_NUMBER 0 #define BUILD_NUMBER 1
#define PATCH_LEVEL 0 #define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise. // Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.) // (Boolean macro values are not supported by all preprocessors.)

49
deps/v8/src/x64/code-stubs-x64.cc

@ -30,7 +30,6 @@
#if defined(V8_TARGET_ARCH_X64) #if defined(V8_TARGET_ARCH_X64)
#include "bootstrapper.h" #include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h" #include "code-stubs.h"
#include "regexp-macro-assembler.h" #include "regexp-macro-assembler.h"
#include "stub-cache.h" #include "stub-cache.h"
@ -4273,10 +4272,6 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
Label invoke, handler_entry, exit; Label invoke, handler_entry, exit;
Label not_outermost_js, not_outermost_js_2; Label not_outermost_js, not_outermost_js_2;
#ifdef _WIN64
const int kCalleeSaveXMMRegisters = 10;
const int kFullXMMRegisterSize = 16;
#endif
{ // NOLINT. Scope block confuses linter. { // NOLINT. Scope block confuses linter.
MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
// Set up frame. // Set up frame.
@ -4306,17 +4301,17 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
#ifdef _WIN64 #ifdef _WIN64
// On Win64 XMM6-XMM15 are callee-save // On Win64 XMM6-XMM15 are callee-save
__ subq(rsp, Immediate(kCalleeSaveXMMRegisters * kFullXMMRegisterSize)); __ subq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize));
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 0), xmm6); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0), xmm6);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 1), xmm7); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1), xmm7);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 2), xmm8); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 2), xmm8);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 3), xmm9); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 3), xmm9);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 4), xmm10); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 4), xmm10);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 5), xmm11); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 5), xmm11);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 6), xmm12); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 6), xmm12);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 7), xmm13); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 7), xmm13);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 8), xmm14); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 8), xmm14);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 9), xmm15); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 9), xmm15);
#endif #endif
// Set up the roots and smi constant registers. // Set up the roots and smi constant registers.
@ -4409,17 +4404,17 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Restore callee-saved registers (X64 conventions). // Restore callee-saved registers (X64 conventions).
#ifdef _WIN64 #ifdef _WIN64
// On Win64 XMM6-XMM15 are callee-save // On Win64 XMM6-XMM15 are callee-save
__ movdqu(xmm6, Operand(rsp, kFullXMMRegisterSize * 0)); __ movdqu(xmm6, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0));
__ movdqu(xmm7, Operand(rsp, kFullXMMRegisterSize * 1)); __ movdqu(xmm7, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1));
__ movdqu(xmm8, Operand(rsp, kFullXMMRegisterSize * 2)); __ movdqu(xmm8, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 2));
__ movdqu(xmm8, Operand(rsp, kFullXMMRegisterSize * 3)); __ movdqu(xmm9, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 3));
__ movdqu(xmm10, Operand(rsp, kFullXMMRegisterSize * 4)); __ movdqu(xmm10, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 4));
__ movdqu(xmm11, Operand(rsp, kFullXMMRegisterSize * 5)); __ movdqu(xmm11, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 5));
__ movdqu(xmm12, Operand(rsp, kFullXMMRegisterSize * 6)); __ movdqu(xmm12, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 6));
__ movdqu(xmm13, Operand(rsp, kFullXMMRegisterSize * 7)); __ movdqu(xmm13, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 7));
__ movdqu(xmm14, Operand(rsp, kFullXMMRegisterSize * 8)); __ movdqu(xmm14, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 8));
__ movdqu(xmm15, Operand(rsp, kFullXMMRegisterSize * 9)); __ movdqu(xmm15, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 9));
__ addq(rsp, Immediate(kCalleeSaveXMMRegisters * kFullXMMRegisterSize)); __ addq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize));
#endif #endif
__ pop(rbx); __ pop(rbx);

2
deps/v8/src/x64/code-stubs-x64.h

@ -138,7 +138,7 @@ class UnaryOpStub: public PlatformCodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::UNARY_OP_IC; } virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() { virtual InlineCacheState GetICState() {
return UnaryOpIC::ToState(operand_type_); return UnaryOpIC::ToState(operand_type_);

7
deps/v8/src/x64/frames-x64.h

@ -51,7 +51,12 @@ const int kNumSafepointRegisters = 16;
class EntryFrameConstants : public AllStatic { class EntryFrameConstants : public AllStatic {
public: public:
#ifdef _WIN64 #ifdef _WIN64
static const int kCallerFPOffset = -10 * kPointerSize; static const int kCalleeSaveXMMRegisters = 10;
static const int kXMMRegisterSize = 16;
static const int kXMMRegistersBlockSize =
kXMMRegisterSize * kCalleeSaveXMMRegisters;
static const int kCallerFPOffset =
-10 * kPointerSize - kXMMRegistersBlockSize;
#else #else
static const int kCallerFPOffset = -8 * kPointerSize; static const int kCallerFPOffset = -8 * kPointerSize;
#endif #endif

12
deps/v8/src/x64/full-codegen-x64.cc

@ -3968,18 +3968,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
case Token::ADD: {
Comment cmt(masm_, "[ UnaryOperation (ADD)");
VisitForAccumulatorValue(expr->expression());
Label no_conversion;
__ JumpIfSmi(result_register(), &no_conversion);
ToNumberStub convert_stub;
__ CallStub(&convert_stub);
__ bind(&no_conversion);
context()->Plug(result_register());
break;
}
case Token::SUB: case Token::SUB:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break; break;

19
deps/v8/src/x64/lithium-codegen-x64.cc

@ -370,7 +370,7 @@ bool LCodeGen::GenerateDeferredCode() {
LDeferredCode* code = deferred_[i]; LDeferredCode* code = deferred_[i];
__ bind(code->entry()); __ bind(code->entry());
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred build frame", Comment(";;; Deferred build frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(!frame_is_built_); ASSERT(!frame_is_built_);
@ -387,7 +387,7 @@ bool LCodeGen::GenerateDeferredCode() {
code->instr()->Mnemonic()); code->instr()->Mnemonic());
code->Generate(); code->Generate();
if (NeedsDeferredFrame()) { if (NeedsDeferredFrame()) {
Comment(";;; Deferred destroy frame", Comment(";;; Deferred destroy frame @%d: %s.",
code->instruction_index(), code->instruction_index(),
code->instr()->Mnemonic()); code->instr()->Mnemonic());
ASSERT(frame_is_built_); ASSERT(frame_is_built_);
@ -926,11 +926,9 @@ void LCodeGen::RecordPosition(int position) {
void LCodeGen::DoLabel(LLabel* label) { void LCodeGen::DoLabel(LLabel* label) {
if (label->is_loop_header()) { Comment(";;; -------------------- B%d%s --------------------",
Comment(";;; B%d - LOOP entry", label->block_id()); label->block_id(),
} else { label->is_loop_header() ? " (loop header)" : "");
Comment(";;; B%d", label->block_id());
}
__ bind(label->label()); __ bind(label->label());
current_block_ = label->block_id(); current_block_ = label->block_id();
DoGap(label); DoGap(label);
@ -2055,11 +2053,14 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
Register right = ToRegister(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id()); int true_block = chunk_->LookupDestination(instr->true_block_id());
__ cmpq(left, right); if (instr->right()->IsConstantOperand()) {
__ Cmp(left, ToHandle(LConstantOperand::cast(instr->right())));
} else {
__ cmpq(left, ToRegister(instr->right()));
}
EmitBranch(true_block, false_block, equal); EmitBranch(true_block, false_block, equal);
} }

3
deps/v8/src/x64/lithium-codegen-x64.h

@ -34,6 +34,7 @@
#include "deoptimizer.h" #include "deoptimizer.h"
#include "safepoint-table.h" #include "safepoint-table.h"
#include "scopes.h" #include "scopes.h"
#include "v8utils.h"
#include "x64/lithium-gap-resolver-x64.h" #include "x64/lithium-gap-resolver-x64.h"
namespace v8 { namespace v8 {
@ -172,7 +173,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); } int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
void Abort(const char* reason); void Abort(const char* reason);
void Comment(const char* format, ...); void FPRINTF_CHECKING Comment(const char* format, ...);
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }

12
deps/v8/src/x64/lithium-x64.cc

@ -831,11 +831,15 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
HEnvironment* last_environment = pred->last_environment(); HEnvironment* last_environment = pred->last_environment();
for (int i = 0; i < block->phis()->length(); ++i) { for (int i = 0; i < block->phis()->length(); ++i) {
HPhi* phi = block->phis()->at(i); HPhi* phi = block->phis()->at(i);
last_environment->SetValueAt(phi->merged_index(), phi); if (phi->merged_index() < last_environment->length()) {
last_environment->SetValueAt(phi->merged_index(), phi);
}
} }
for (int i = 0; i < block->deleted_phis()->length(); ++i) { for (int i = 0; i < block->deleted_phis()->length(); ++i) {
last_environment->SetValueAt(block->deleted_phis()->at(i), if (block->deleted_phis()->at(i) < last_environment->length()) {
graph_->GetConstantUndefined()); last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
} }
block->UpdateEnvironment(last_environment); block->UpdateEnvironment(last_environment);
// Pick up the outgoing argument count of one of the predecessors. // Pick up the outgoing argument count of one of the predecessors.
@ -1610,7 +1614,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
HCompareObjectEqAndBranch* instr) { HCompareObjectEqAndBranch* instr) {
LOperand* left = UseRegisterAtStart(instr->left()); LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right()); LOperand* right = UseRegisterOrConstantAtStart(instr->right());
return new(zone()) LCmpObjectEqAndBranch(left, right); return new(zone()) LCmpObjectEqAndBranch(left, right);
} }

105
deps/v8/test/benchmarks/testcfg.py

@ -1,105 +0,0 @@
# Copyright 2011 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import test
import os
from os.path import join, split
def GetSuite(name, root):
# Not implemented.
return None
def IsNumber(string):
try:
float(string)
return True
except ValueError:
return False
class BenchmarkTestCase(test.TestCase):
def __init__(self, path, context, mode):
super(BenchmarkTestCase, self).__init__(context, split(path), mode)
self.root = path
def GetLabel(self):
return '%s benchmark %s' % (self.mode, self.GetName())
def IsFailureOutput(self, output):
if output.exit_code != 0:
return True
lines = output.stdout.splitlines()
for line in lines:
colon_index = line.find(':')
if colon_index >= 0:
if not IsNumber(line[colon_index+1:].strip()):
return True
return False
def GetCommand(self):
result = self.context.GetVmCommand(self, self.mode)
result.append(join(self.root, 'run.js'))
return result
def GetName(self):
return 'V8'
def BeforeRun(self):
os.chdir(self.root)
def AfterRun(self, result):
os.chdir(self.context.buildspace)
def GetSource(self):
return open(join(self.root, 'run.js')).read()
def GetCustomFlags(self, mode):
return []
class BenchmarkTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(BenchmarkTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, variant_flags):
path = self.context.workspace
path = join(path, 'benchmarks')
test = BenchmarkTestCase(path, self.context, mode)
return [test]
def GetBuildRequirements(self):
return ['d8']
def GetTestStatus(self, sections, defs):
pass
def GetConfiguration(context, root):
return BenchmarkTestConfiguration(context, root)

152
deps/v8/test/cctest/SConscript

@ -1,152 +0,0 @@
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import sys
from os.path import join, dirname, abspath
root_dir = dirname(File('SConstruct').rfile().abspath)
sys.path.append(join(root_dir, 'tools'))
import js2c
Import('context object_files tools')
# Needed for test-log. Paths are relative to the cctest dir.
JS_FILES_FOR_TESTS = [
'../../../tools/splaytree.js',
'../../../tools/codemap.js',
'../../../tools/csvparser.js',
'../../../tools/consarray.js',
'../../../tools/profile.js',
'../../../tools/profile_view.js',
'../../../tools/logreader.js',
'log-eq-of-logging-and-traversal.js',
]
SOURCES = {
'all': [
'gay-fixed.cc',
'gay-precision.cc',
'gay-shortest.cc',
'test-accessors.cc',
'test-alloc.cc',
'test-api.cc',
'test-ast.cc',
'test-bignum-dtoa.cc',
'test-bignum.cc',
'test-circular-queue.cc',
'test-compiler.cc',
'test-conversions.cc',
'test-cpu-profiler.cc',
'test-dataflow.cc',
'test-date.cc',
'test-debug.cc',
'test-declarative-accessors.cc',
'test-decls.cc',
'test-deoptimization.cc',
'test-dictionary.cc',
'test-diy-fp.cc',
'test-double.cc',
'test-dtoa.cc',
'test-fast-dtoa.cc',
'test-fixed-dtoa.cc',
'test-flags.cc',
'test-func-name-inference.cc',
'test-hashing.cc',
'test-hashmap.cc',
'test-heap-profiler.cc',
'test-heap.cc',
'test-list.cc',
'test-liveedit.cc',
'test-lock.cc',
'test-lockers.cc',
'test-log.cc',
'test-mark-compact.cc',
'test-parsing.cc',
'test-platform-tls.cc',
'test-profile-generator.cc',
'test-random.cc',
'test-regexp.cc',
'test-reloc-info.cc',
'test-serialize.cc',
'test-sockets.cc',
'test-spaces.cc',
'test-strings.cc',
'test-symbols.cc',
'test-strtod.cc',
'test-thread-termination.cc',
'test-threads.cc',
'test-unbound-queue.cc',
'test-utils.cc',
'test-version.cc',
'test-weakmaps.cc'
],
'arch:arm': [
'test-assembler-arm.cc',
'test-disasm-arm.cc'
],
'arch:ia32': [
'test-assembler-ia32.cc',
'test-disasm-ia32.cc',
'test-log-stack-tracer.cc'
],
'arch:x64': ['test-assembler-x64.cc',
'test-macro-assembler-x64.cc',
'test-log-stack-tracer.cc',
'test-disasm-x64.cc'],
'arch:mips': ['test-assembler-mips.cc',
'test-disasm-mips.cc'],
'os:linux': ['test-platform-linux.cc'],
'os:macos': ['test-platform-macos.cc'],
'os:nullos': ['test-platform-nullos.cc'],
'os:win32': ['test-platform-win32.cc']
}
def Build():
cctest_files = context.GetRelevantSources(SOURCES)
env = Environment(tools=tools)
env.Replace(**context.flags['cctest'])
context.ApplyEnvOverrides(env)
env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
# Combine the JavaScript library files into a single C++ file and
# compile it.
js_files = [s for s in JS_FILES_FOR_TESTS]
js_files_src = env.JS2C(
['js-files-for-cctest.cc'], js_files, **{'TYPE': 'TEST', 'COMPRESSION': 'off'})
js_files_obj = context.ConfigureObject(env, js_files_src, CPPPATH=['.'])
# There seems to be a glitch in the way scons decides where to put
# PDB files when compiling using MSVC so we specify it manually.
# This should not affect any other platforms.
object_files.append(js_files_obj)
return env.Program('cctest', ['cctest.cc', cctest_files, object_files],
PDB='cctest.exe.pdb')
program = Build()
Return('program')

4
deps/v8/test/cctest/cctest.gyp

@ -159,7 +159,9 @@
'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'], 'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
}, },
{ {
'dependencies': ['../../tools/gyp/v8.gyp:v8_nosnapshot'], 'dependencies': [
'../../tools/gyp/v8.gyp:v8_nosnapshot.<(v8_target_arch)',
],
}], }],
], ],
}, { }, {

97
deps/v8/test/cctest/testcfg.py

@ -84,100 +84,3 @@ class CcTestSuite(testsuite.TestSuite):
def GetSuite(name, root): def GetSuite(name, root):
return CcTestSuite(name, root) return CcTestSuite(name, root)
# Deprecated definitions below.
# TODO(jkummerow): Remove when SCons is no longer supported.
from os.path import exists, join, normpath
import test
class CcTestCase(test.TestCase):
def __init__(self, path, executable, mode, raw_name, dependency, context, variant_flags):
super(CcTestCase, self).__init__(context, path, mode)
self.executable = executable
self.raw_name = raw_name
self.dependency = dependency
self.variant_flags = variant_flags
def GetLabel(self):
return "%s %s %s" % (self.mode, self.path[-2], self.path[-1])
def GetName(self):
return self.path[-1]
def BuildCommand(self, name):
serialization_file = ''
if exists(join(self.context.buildspace, 'obj', 'test', self.mode)):
serialization_file = join('obj', 'test', self.mode, 'serdes')
else:
serialization_file = join('obj', 'serdes')
if not exists(join(self.context.buildspace, 'obj')):
os.makedirs(join(self.context.buildspace, 'obj'))
serialization_file += '_' + self.GetName()
serialization_file = join(self.context.buildspace, serialization_file)
serialization_file += ''.join(self.variant_flags).replace('-', '_')
serialization_option = '--testing_serialization_file=' + serialization_file
result = [ self.executable, name, serialization_option ]
result += self.context.GetVmFlags(self, self.mode)
return result
def GetCommand(self):
return self.BuildCommand(self.raw_name)
def Run(self):
if self.dependency != '':
dependent_command = self.BuildCommand(self.dependency)
output = self.RunCommand(dependent_command)
if output.HasFailed():
return output
return test.TestCase.Run(self)
class CcTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(CcTestConfiguration, self).__init__(context, root)
def GetBuildRequirements(self):
return ['cctests']
def ListTests(self, current_path, path, mode, variant_flags):
executable = 'cctest'
if utils.IsWindows():
executable += '.exe'
executable = join(self.context.buildspace, executable)
if not exists(executable):
executable = join('obj', 'test', mode, 'cctest')
if utils.IsWindows():
executable += '.exe'
executable = join(self.context.buildspace, executable)
full_command = self.context.processor([executable, '--list'])
output = test.Execute(full_command, self.context)
if output.exit_code != 0:
print output.stdout
print output.stderr
return []
result = []
for test_desc in output.stdout.strip().split():
raw_test, dependency = test_desc.split('<')
relative_path = raw_test.split('/')
full_path = current_path + relative_path
if dependency != '':
dependency = relative_path[0] + '/' + dependency
if self.Contains(path, full_path):
result.append(CcTestCase(full_path, executable, mode, raw_test, dependency, self.context, variant_flags))
result.sort()
return result
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'cctest.status')
if exists(status_file):
test.ReadConfigurationInto(status_file, sections, defs)
def GetConfiguration(context, root):
return CcTestConfiguration(context, root)

14
deps/v8/test/es5conform/README

@ -1,14 +0,0 @@
This directory contains code for binding the es5conform test suite
into the v8 test harness. To use the tests check out the es5conform
tests from
https://es5conform.svn.codeplex.com/svn
in revision 71525 as 'data' in this directory. Using later version
may be possible but the tests are only known to pass (and indeed run)
with that revision.
If you do update to a newer revision you may have to change the test
harness adapter code since it uses internal functionality from the
harness that comes bundled with the tests. You will most likely also
have to update the test expectation file.

316
deps/v8/test/es5conform/es5conform.status

@ -1,316 +0,0 @@
# Copyright 2009 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
prefix es5conform
def UNIMPLEMENTED = PASS || FAIL
def FAIL_OK = FAIL, OKAY
##############################################################################
# Non UTF8 characters in test files.
chapter10/10.4/10.4.2/10.4.2-3-c-2-s: FAIL_OK
chapter10/10.4/10.4.2/10.4.2-3-c-1-s: FAIL_OK
chapter10/10.4/10.4.2/10.4.2-2-c-1: FAIL_OK
# We do not implement the error chekcs specified in the production rules
# of 11.1.5 (Object initializer).
# We are compatible with Safari and Firefox.
chapter11/11.1/11.1.5: UNIMPLEMENTED
# Our Function object has an "arguments" property which is used as a
# non-property in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK
# Our Function object has a "caller" property which is used as a
# non-property in in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-184: FAIL_OK
# Our function object has a name property which is used as a
# non-property in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-188: FAIL_OK
# NOT IMPLEMENTED: RegExp.prototype.source
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-212: UNIMPLEMENTED
# NOT IMPLEMENTED: RegExp.prototype.global
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-213: UNIMPLEMENTED
# NOT IMPLEMENTED: RegExp.prototype.ignoreCase
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-214: UNIMPLEMENTED
# NOT IMPLEMENTED: RegExp.prototype.multiline
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215: UNIMPLEMENTED
# All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because
# the tests assumes that objects can not have more properties
# than those described in the spec - but according to spec they can
# have additional properties.
# All compareArray calls in these tests could be exchanged with a
# isSubsetOfArray call (I will upload a patch to the es5conform site).
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-1: FAIL_OK
# SUBSETFAIL + we do not implement all methods on Object.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-2: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-3: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-4: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-5: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-6: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-7: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-11: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-14: FAIL_OK
# EvalError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-15: FAIL
# Rangeerror.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-16: FAIL
# ReferenceError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-17: FAIL
# SyntaxError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-18: FAIL
# TypeError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-19: FAIL
# URIError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-20: FAIL
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-22: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-23: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-24: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-25: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-26: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-27: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-28: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-29: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-30: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-31: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-32: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-33: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-34: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-35: FAIL_OK
# Bad test - the test at the end should be "i === true".
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-8-10: FAIL_OK
# Bad test - according to spec some returns a Boolean, not a number.
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-4-9: FAIL_OK
# Bad test - uses unitialized variable a in precondition check.
chapter15/15.4/15.4.4/15.4.4.19/15.4.4.19-9-3: FAIL_OK
# We do not implement Array mapping functions correctly if array
# entries are added for nonexistent entries smaller than length by
# the callback function. We are compatible with JSC.
# See http://code.google.com/p/v8/issues/detail?id=755
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-1: FAIL_OK
# Bad tests, path in test file is wrong. This will crash the test
# script so we mark it SKIP.
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4: SKIP
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4-s: SKIP
# Bad test - deleting the property on o in callbackfn will
# have no effect on the actual array on which reduceRight is called.
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-7: FAIL_OK
##############################################################################
# Unimplemented parts of strict mode
# Setting expectations to fail only so that the tests trigger as soon as
# the strict mode feature gets implemented
# A directive preceeding an 'use strict' directive may not contain
# an OctalEscapeSequence
# Incorrect test - need double escape in eval.
chapter07/7.8/7.8.4/7.8.4-1-s: FAIL
# arguments.caller is non-configurable in strict mode
# Invalid test case. Checks for "writable == true" and presence of "put"..
chapter10/10.6/10.6-13-b-3-s: FAIL
# arguments.callee is non-configurable in strict mode
# Invalid test case. Checks for "put" property accessor.
chapter10/10.6/10.6-13-c-3-s: FAIL
# simple assignment throws TypeError if LeftHandSide is a property reference
# with a primitive base value (this is undefined)
chapter11/11.13/11.13.1/11.13.1-1-7-s: FAIL
# simple assignment throws TypeError if LeftHandSide is a readonly property
# in strict mode (Global.NaN)
chapter11/11.13/11.13.1/11.13.1-4-2-s: FAIL
# simple assignment throws TypeError if LeftHandSide is a readonly property
# in strict mode (Global.Infinity)
chapter11/11.13/11.13.1/11.13.1-4-3-s: FAIL
# simple assignment throws TypeError if LeftHandSide is a readonly property
# in strict mode (Global.length)
chapter11/11.13/11.13.1/11.13.1-4-4-s: FAIL
# simple assignment throws TypeError if LeftHandSide is a readonly property
# in strict mode (Global.undefined)
chapter11/11.13/11.13.1/11.13.1-4-27-s: FAIL
# delete operator throws TypeError when when deleting a non-configurable
# data property in strict mode (Global.NaN)
# Invalid test case - "this" is not a global object within the test case.
# (http://es5conform.codeplex.com/workitem/29151)
chapter11/11.4/11.4.1/11.4.1-4.a-4-s: FAIL_OK
# delete operator throws ReferenceError when deleting a direct reference
# to a var in strict mode
# Invalid test case. Test expects ReferenceError instead of SyntaxError.
# http://es5conform.codeplex.com/workitem/29084
chapter11/11.4/11.4.1/11.4.1-5-1-s: FAIL
# delete operator throws ReferenceError when deleting a direct reference
# to a function argument in strict mode
# Invalid test case. Test expects ReferenceError instead of SyntaxError.
# http://es5conform.codeplex.com/workitem/29084
chapter11/11.4/11.4.1/11.4.1-5-2-s: FAIL
# delete operator throws ReferenceError when deleting a direct reference
# to a function name in strict mode
# Invalid test case. Test expects ReferenceError instead of SyntaxError.
# http://es5conform.codeplex.com/workitem/29084
chapter11/11.4/11.4.1/11.4.1-5-3-s: FAIL
# eval - a function declaring a var named 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-1-s: FAIL
# eval - a function assigning into 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-2-s: FAIL
# eval - a function expr declaring a var named 'eval' throws EvalError
# in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-3-s: FAIL
# eval - a function expr assigning into 'eval' throws a EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-4-s: FAIL
# eval - a Function declaring var named 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-5-s: FAIL
# eval - a Function assigning into 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-6-s: FAIL
# eval - a direct eval declaring a var named 'eval' throws EvalError
# in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-7-s: FAIL
# eval - a direct eval assigning into 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-8-s: FAIL
# eval - an indirect eval declaring a var named 'eval' throws EvalError
# in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-9-s: FAIL
# eval - an indirect eval assigning into 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError.
chapter12/12.2/12.2.1/12.2.1-10-s: FAIL
# SyntaxError if eval used as function identifier in function declaration
# with strict body
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-3-s: FAIL
# SyntaxError if eval used as function identifier in function expression
# with strict body
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-4-s: FAIL
# SyntaxError if eval used as function identifier in function declaration
# in strict code
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-5-s: FAIL
# SyntaxError if eval used as function identifier in function expression
# in strict code
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-6-s: FAIL
# SyntaxError if arguments used as function identifier in function declaration
# with strict body
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-9-s: FAIL
# SyntaxError if arguments used as function identifier in function expression
# with strict body
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-10-s: FAIL
# SyntaxError if arguments used as function identifier in function declaration
# in strict code
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-11-s: FAIL
# SyntaxError if arguments used as function identifier in function expression
# in strict code
# Test fails to return true on success (invalid test case).
chapter13/13.1/13.1-3-12-s: FAIL
# Duplicate combined parameter name allowed in Function constructor called
# in strict mode if body not strict
# Test fails to return true on success (invalid test case).
chapter15/15.3/15.3.2/15.3.2.1/15.3.2.1-11-6-s: FAIL
# Array.prototype.reduce - null passed as thisValue to strict callbackfn
# Invalid test case: http://es5conform.codeplex.com/workitem/29085
chapter15/15.4/15.4.4/15.4.4.21/15.4.4.21-9-c-ii-4-s: FAIL

74
deps/v8/test/es5conform/harness-adapt.js

@ -1,74 +0,0 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var global = this;
function ES5Error(ut) {
this.ut = ut;
}
ES5Error.prototype.toString = function () {
return this.ut.res;
};
// The harness uses the IE specific .description property of exceptions but
// that's nothing we can't hack our way around.
Error.prototype.__defineGetter__('description', function () {
return this.message;
});
function TestHarness() {
sth.call(this, global);
this._testResults = []
}
// Borrow sth's registerTest method.
TestHarness.prototype.registerTest = sth.prototype.registerTest;
// Drop the before/after stuff, just run the test.
TestHarness.prototype.startTesting = function () {
sth.prototype.run.call(this);
this.report();
};
TestHarness.prototype.report = function () {
for (var i = 0; i < this._testResults.length; i++) {
var ut = this._testResults[i];
// We don't fail on preconditions. Yet.
if (ut.res == "Precondition failed")
continue;
if (ut.res != 'pass')
throw new ES5Error(ut);
}
};
TestHarness.prototype.startingTest = function (ut) {
this.currentTest = ut;
this._testResults.push(ut);
};
var ES5Harness = new TestHarness();

114
deps/v8/test/es5conform/testcfg.py

@ -1,114 +0,0 @@
# Copyright 2008 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import test
import os
from os.path import join, exists
def GetSuite(name, root):
# Not implemented.
return None
HARNESS_FILES = ['sth.js']
class ES5ConformTestCase(test.TestCase):
def __init__(self, filename, path, context, root, mode, framework):
super(ES5ConformTestCase, self).__init__(context, path, mode)
self.filename = filename
self.framework = framework
self.root = root
def IsNegative(self):
return self.filename.endswith('-n.js')
def GetLabel(self):
return "%s es5conform %s" % (self.mode, self.GetName())
def IsFailureOutput(self, output):
if output.exit_code != 0:
return True
return 'FAILED!' in output.stdout
def GetCommand(self):
result = self.context.GetVmCommand(self, self.mode)
result += ['-e', 'var window = this']
result += self.framework
result.append(self.filename)
result += ['-e', 'ES5Harness.startTesting()']
return result
def GetName(self):
return self.path[-1]
def GetSource(self):
return open(self.filename).read()
class ES5ConformTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(ES5ConformTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, variant_flags):
tests = []
current_root = join(self.root, 'data', 'TestCases')
harness = []
harness += [join(self.root, 'data', 'SimpleTestHarness', f) for f in HARNESS_FILES]
harness += [join(self.root, 'harness-adapt.js')]
for root, dirs, files in os.walk(current_root):
for dotted in [x for x in dirs if x.startswith('.')]:
dirs.remove(dotted)
dirs.sort()
root_path = root[len(self.root):].split(os.path.sep)
root_path = current_path + [x for x in root_path if x]
files.sort()
for file in files:
if file.endswith('.js'):
full_path = root_path + [file[:-3]]
full_path = [x for x in full_path if not (x in ['data', 'TestCases'])]
if self.Contains(path, full_path):
test = ES5ConformTestCase(join(root, file), full_path, self.context,
self.root, mode, harness)
tests.append(test)
return tests
def GetBuildRequirements(self):
return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'es5conform.status')
if exists(status_file):
test.ReadConfigurationInto(status_file, sections, defs)
def GetConfiguration(context, root):
return ES5ConformTestConfiguration(context, root)

115
deps/v8/test/message/testcfg.py

@ -50,7 +50,7 @@ class MessageTestSuite(testsuite.TestSuite):
files.sort() files.sort()
for filename in files: for filename in files:
if filename.endswith(".js"): if filename.endswith(".js"):
testname = join(dirname[len(self.root) + 1:], filename[:-3]) testname = os.path.join(dirname[len(self.root) + 1:], filename[:-3])
test = testcase.TestCase(self, testname) test = testcase.TestCase(self, testname)
tests.append(test) tests.append(test)
return tests return tests
@ -109,116 +109,3 @@ class MessageTestSuite(testsuite.TestSuite):
def GetSuite(name, root): def GetSuite(name, root):
return MessageTestSuite(name, root) return MessageTestSuite(name, root)
# Deprecated definitions below.
# TODO(jkummerow): Remove when SCons is no longer supported.
import test
from os.path import join, exists, basename, isdir
class MessageTestCase(test.TestCase):
def __init__(self, path, file, expected, mode, context, config):
super(MessageTestCase, self).__init__(context, path, mode)
self.file = file
self.expected = expected
self.config = config
def IgnoreLine(self, str):
"""Ignore empty lines, valgrind output and Android output."""
if not str: return True
return (str.startswith('==') or str.startswith('**') or
str.startswith('ANDROID'))
def IsFailureOutput(self, output):
f = file(self.expected)
# Skip initial '#' comment and spaces
for line in f:
if (not line.startswith('#')) and (not line.strip()):
break
# Convert output lines to regexps that we can match
env = { 'basename': basename(self.file) }
patterns = [ ]
for line in f:
if not line.strip():
continue
pattern = re.escape(line.rstrip() % env)
pattern = pattern.replace('\\*', '.*')
pattern = '^%s$' % pattern
patterns.append(pattern)
# Compare actual output with the expected
raw_lines = output.stdout.splitlines()
outlines = [ s for s in raw_lines if not self.IgnoreLine(s) ]
if len(outlines) != len(patterns):
return True
for i in xrange(len(patterns)):
if not re.match(patterns[i], outlines[i]):
return True
return False
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self):
return self.path[-1]
def GetCommand(self):
result = self.config.context.GetVmCommand(self, self.mode)
source = open(self.file).read()
flags_match = re.findall(FLAGS_PATTERN, source)
for match in flags_match:
result += match.strip().split()
result.append(self.file)
return result
def GetSource(self):
return (open(self.file).read()
+ "\n--- expected output ---\n"
+ open(self.expected).read())
class MessageTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(MessageTestConfiguration, self).__init__(context, root)
def Ls(self, path):
if isdir(path):
return [f[:-3] for f in os.listdir(path) if f.endswith('.js')]
else:
return []
def ListTests(self, current_path, path, mode, variant_flags):
mjsunit = [current_path + [t] for t in self.Ls(self.root)]
regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))]
bugs = [current_path + ['bugs', t] for t in self.Ls(join(self.root, 'bugs'))]
mjsunit.sort()
regress.sort()
bugs.sort()
all_tests = mjsunit + regress + bugs
result = []
for test in all_tests:
if self.Contains(path, test):
file_prefix = join(self.root, reduce(join, test[1:], ""))
file_path = file_prefix + ".js"
output_path = file_prefix + ".out"
if not exists(output_path):
print "Could not find %s" % output_path
continue
result.append(MessageTestCase(test, file_path, output_path, mode,
self.context, self))
return result
def GetBuildRequirements(self):
return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'message.status')
if exists(status_file):
test.ReadConfigurationInto(status_file, sections, defs)
def GetConfiguration(context, root):
return MessageTestConfiguration(context, root)

27
deps/v8/test/mjsunit/harmony/generators-objects.js

@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --harmony-generators --harmony-scoping // Flags: --harmony-generators --harmony-scoping --allow-natives-syntax
// Test instantations of generators. // Test instantations of generators.
@ -55,6 +55,8 @@ function TestGeneratorObject() {
var iter = g(); var iter = g();
assertSame(g.prototype, Object.getPrototypeOf(iter)); assertSame(g.prototype, Object.getPrototypeOf(iter));
assertTrue(iter instanceof g); assertTrue(iter instanceof g);
assertEquals("Generator", %ClassOf(iter));
assertEquals("[object Generator]", String(iter));
assertEquals([], Object.getOwnPropertyNames(iter)); assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== g()); assertTrue(iter !== g());
@ -62,7 +64,30 @@ function TestGeneratorObject() {
iter = new g(); iter = new g();
assertSame(g.prototype, Object.getPrototypeOf(iter)); assertSame(g.prototype, Object.getPrototypeOf(iter));
assertTrue(iter instanceof g); assertTrue(iter instanceof g);
assertEquals("Generator", %ClassOf(iter));
assertEquals("[object Generator]", String(iter));
assertEquals([], Object.getOwnPropertyNames(iter)); assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== new g()); assertTrue(iter !== new g());
} }
TestGeneratorObject(); TestGeneratorObject();
// Test the methods of generator objects.
function TestGeneratorObjectMethods() {
function* g() { yield 1; }
var iter = g();
function TestNonGenerator(non_generator) {
assertThrows(function() { iter.next.call(non_generator); }, TypeError);
assertThrows(function() { iter.send.call(non_generator, 1); }, TypeError);
assertThrows(function() { iter.throw.call(non_generator, 1); }, TypeError);
assertThrows(function() { iter.close.call(non_generator); }, TypeError);
}
TestNonGenerator(1);
TestNonGenerator({});
TestNonGenerator(function(){});
TestNonGenerator(g);
TestNonGenerator(g.prototype);
}
TestGeneratorObjectMethods();

2
deps/v8/test/mjsunit/harmony/typedarrays.js

@ -45,9 +45,11 @@ function TestArrayBufferCreation() {
TestByteLength(0, 0); TestByteLength(0, 0);
/* TODO[dslomov]: Reenable the test
assertThrows(function() { assertThrows(function() {
var ab1 = new __ArrayBuffer(0xFFFFFFFFFFFF) var ab1 = new __ArrayBuffer(0xFFFFFFFFFFFF)
}, RangeError); }, RangeError);
*/
var ab = new __ArrayBuffer(); var ab = new __ArrayBuffer();
assertSame(0, ab.byteLength); assertSame(0, ab.byteLength);

31
deps/v8/src/builtins-decls.h → deps/v8/test/mjsunit/regress/regress-grow-store-smi-check.js

@ -25,16 +25,29 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_BUILTINS_DECLS_H_ // Flags: --allow-natives-syntax
#define V8_BUILTINS_DECLS_H_
#include "arguments.h" // The below test function was generated from part of a WebKit layout
// test library setup routine: fast/canvas/webgl/resources/pnglib.js
namespace v8 { function test(crc32) {
namespace internal { for (var i = 0; i < 256; i++) {
var c = i;
for (var j = 0; j < 8; j++) {
if (c & 1) {
c = -306674912 ^ ((c >> 1) & 0x7fffffff);
} else {
c = (c >> 1) & 0x7fffffff;
}
}
crc32[i] = c;
}
}
DECLARE_RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure); var a = [0.5];
for (var i = 0; i < 256; ++i) a[i] = i;
} } // namespace v8::internal test([0.5]);
test(a);
#endif // V8_BUILTINS_DECLS_H_ %OptimizeFunctionOnNextCall(test);
test(a);

21
deps/v8/test/mjsunit/string-fromcharcode.js

@ -25,8 +25,29 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Test String.fromCharCode. // Test String.fromCharCode.
// Test char codes larger than 0xffff.
var expected = "";
for (var i = 100; i < 500; i++) {
expected += String.fromCharCode(i);
}
function testCharCodeTruncation() {
var result = "";
for (var i = 0x100000 + 100; i < 0x100000 + 500; i++) {
result += String.fromCharCode(i);
}
assertEquals(String.fromCharCode(0xFFFF), String.fromCharCode(0xFFFFFFFF));
return result;
}
assertEquals(expected, testCharCodeTruncation());
assertEquals(expected, testCharCodeTruncation());
%OptimizeFunctionOnNextCall(testCharCodeTruncation);
assertEquals(expected, testCharCodeTruncation());
// Test various receivers and arguments passed to String.fromCharCode. // Test various receivers and arguments passed to String.fromCharCode.

133
deps/v8/test/mjsunit/testcfg.py

@ -50,7 +50,7 @@ class MjsunitTestSuite(testsuite.TestSuite):
files.sort() files.sort()
for filename in files: for filename in files:
if filename.endswith(".js") and filename != "mjsunit.js": if filename.endswith(".js") and filename != "mjsunit.js":
testname = join(dirname[len(self.root) + 1:], filename[:-3]) testname = os.path.join(dirname[len(self.root) + 1:], filename[:-3])
test = testcase.TestCase(self, testname) test = testcase.TestCase(self, testname)
tests.append(test) tests.append(test)
return tests return tests
@ -95,134 +95,3 @@ class MjsunitTestSuite(testsuite.TestSuite):
def GetSuite(name, root): def GetSuite(name, root):
return MjsunitTestSuite(name, root) return MjsunitTestSuite(name, root)
# Deprecated definitions below.
# TODO(jkummerow): Remove when SCons is no longer supported.
from os.path import dirname, exists, join, normpath
import tempfile
import test
class MjsunitTestCase(test.TestCase):
def __init__(self, path, file, mode, context, config, isolates):
super(MjsunitTestCase, self).__init__(context, path, mode)
self.file = file
self.config = config
self.self_script = False
self.isolates = isolates
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self):
return self.path[-1] + ["", "-isolates"][self.isolates]
def TestsIsolates(self):
return self.isolates
def GetVmCommand(self, source):
result = self.config.context.GetVmCommand(self, self.mode)
flags_match = re.findall(FLAGS_PATTERN, source);
for match in flags_match:
result += match.strip().split()
return result
def GetVmArguments(self, source):
result = []
additional_files = []
files_match = FILES_PATTERN.search(source);
# Accept several lines of 'Files:'
while True:
if files_match:
additional_files += files_match.group(1).strip().split()
files_match = FILES_PATTERN.search(source, files_match.end())
else:
break
for a_file in additional_files:
result.append(join(dirname(self.config.root), '..', a_file))
framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js')
if SELF_SCRIPT_PATTERN.search(source):
result.append(self.CreateSelfScript())
result += [framework, self.file]
return result
def GetCommand(self):
source = open(self.file).read()
result = self.GetVmCommand(source)
result += self.GetVmArguments(source)
if self.isolates:
result.append("--isolate")
result += self.GetVmArguments(source)
return result
def GetSource(self):
return open(self.file).read()
def CreateSelfScript(self):
(fd_self_script, self_script) = tempfile.mkstemp(suffix=".js")
def MakeJsConst(name, value):
return "var %(name)s=\'%(value)s\';\n" % \
{'name': name, \
'value': value.replace('\\', '\\\\').replace('\'', '\\\'') }
try:
os.write(fd_self_script, MakeJsConst('TEST_FILE_NAME', self.file))
except IOError, e:
test.PrintError("write() " + str(e))
os.close(fd_self_script)
self.self_script = self_script
return self_script
def AfterRun(self, result):
if self.self_script and (not result or (not result.HasPreciousOutput())):
test.CheckedUnlink(self.self_script)
class MjsunitTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(MjsunitTestConfiguration, self).__init__(context, root)
def Ls(self, path):
def SelectTest(name):
return name.endswith('.js') and name != 'mjsunit.js'
return [f[:-3] for f in os.listdir(path) if SelectTest(f)]
def ListTests(self, current_path, path, mode, variant_flags):
mjsunit = [current_path + [t] for t in self.Ls(self.root)]
regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))]
bugs = [current_path + ['bugs', t] for t in self.Ls(join(self.root, 'bugs'))]
third_party = [current_path + ['third_party', t] for t in self.Ls(join(self.root, 'third_party'))]
tools = [current_path + ['tools', t] for t in self.Ls(join(self.root, 'tools'))]
compiler = [current_path + ['compiler', t] for t in self.Ls(join(self.root, 'compiler'))]
harmony = [current_path + ['harmony', t] for t in self.Ls(join(self.root, 'harmony'))]
mjsunit.sort()
regress.sort()
bugs.sort()
third_party.sort()
tools.sort()
compiler.sort()
harmony.sort()
all_tests = mjsunit + regress + bugs + third_party + tools + compiler + harmony
result = []
for test in all_tests:
if self.Contains(path, test):
file_path = join(self.root, reduce(join, test[1:], "") + ".js")
result.append(MjsunitTestCase(test, file_path, mode, self.context, self, False))
result.append(MjsunitTestCase(test, file_path, mode, self.context, self, True))
return result
def GetBuildRequirements(self):
return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'mjsunit.status')
if exists(status_file):
test.ReadConfigurationInto(status_file, sections, defs)
def GetConfiguration(context, root):
return MjsunitTestConfiguration(context, root)

97
deps/v8/test/mozilla/testcfg.py

@ -104,7 +104,7 @@ class MozillaTestSuite(testsuite.TestSuite):
return testcase.flags + result return testcase.flags + result
def GetSourceForTest(self, testcase): def GetSourceForTest(self, testcase):
filename = join(self.testroot, testcase.path + ".js") filename = os.path.join(self.testroot, testcase.path + ".js")
with open(filename) as f: with open(filename) as f:
return f.read() return f.read()
@ -150,7 +150,7 @@ class MozillaTestSuite(testsuite.TestSuite):
if code != 0: if code != 0:
os.chdir(old_cwd) os.chdir(old_cwd)
raise Exception("Error checking out Mozilla test suite!") raise Exception("Error checking out Mozilla test suite!")
os.rename(join("mozilla", "js", "tests"), directory_name) os.rename(os.path.join("mozilla", "js", "tests"), directory_name)
shutil.rmtree("mozilla") shutil.rmtree("mozilla")
with tarfile.open(archive_file, "w:gz") as tar: with tarfile.open(archive_file, "w:gz") as tar:
tar.add("data") tar.add("data")
@ -161,96 +161,3 @@ class MozillaTestSuite(testsuite.TestSuite):
def GetSuite(name, root): def GetSuite(name, root):
return MozillaTestSuite(name, root) return MozillaTestSuite(name, root)
# Deprecated definitions below.
# TODO(jkummerow): Remove when SCons is no longer supported.
from os.path import exists
from os.path import join
import test
class MozillaTestCase(test.TestCase):
def __init__(self, filename, path, context, root, mode, framework):
super(MozillaTestCase, self).__init__(context, path, mode)
self.filename = filename
self.framework = framework
self.root = root
def IsNegative(self):
return self.filename.endswith('-n.js')
def GetLabel(self):
return "%s mozilla %s" % (self.mode, self.GetName())
def IsFailureOutput(self, output):
if output.exit_code != 0:
return True
return 'FAILED!' in output.stdout
def GetCommand(self):
result = self.context.GetVmCommand(self, self.mode) + \
[ '--expose-gc', join(self.root, 'mozilla-shell-emulation.js') ]
result += [ '--es5_readonly' ] # Temporary hack until we can remove flag
result += self.framework
result.append(self.filename)
return result
def GetName(self):
return self.path[-1]
def GetSource(self):
return open(self.filename).read()
class MozillaTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(MozillaTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, variant_flags):
tests = []
for test_dir in TEST_DIRS:
current_root = join(self.root, 'data', test_dir)
for root, dirs, files in os.walk(current_root):
for dotted in [x for x in dirs if x.startswith('.')]:
dirs.remove(dotted)
for excluded in EXCLUDED:
if excluded in dirs:
dirs.remove(excluded)
dirs.sort()
root_path = root[len(self.root):].split(os.path.sep)
root_path = current_path + [x for x in root_path if x]
framework = []
for i in xrange(len(root_path)):
if i == 0: dir = root_path[1:]
else: dir = root_path[1:-i]
script = join(self.root, reduce(join, dir, ''), 'shell.js')
if exists(script):
framework.append(script)
framework.reverse()
files.sort()
for file in files:
if (not file in FRAMEWORK) and file.endswith('.js'):
full_path = root_path + [file[:-3]]
full_path = [x for x in full_path if x != 'data']
if self.Contains(path, full_path):
test = MozillaTestCase(join(root, file), full_path, self.context,
self.root, mode, framework)
tests.append(test)
return tests
def GetBuildRequirements(self):
return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'mozilla.status')
if exists(status_file):
test.ReadConfigurationInto(status_file, sections, defs)
def GetConfiguration(context, root):
return MozillaTestConfiguration(context, root)

144
deps/v8/test/preparser/testcfg.py

@ -42,7 +42,7 @@ class PreparserTestSuite(testsuite.TestSuite):
return "preparser" return "preparser"
def _GetExpectations(self): def _GetExpectations(self):
expects_file = join(self.root, "preparser.expectation") expects_file = os.path.join(self.root, "preparser.expectation")
expectations_map = {} expectations_map = {}
if not os.path.exists(expects_file): return expectations_map if not os.path.exists(expects_file): return expectations_map
rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$") rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$")
@ -58,7 +58,7 @@ class PreparserTestSuite(testsuite.TestSuite):
return expectations_map return expectations_map
def _ParsePythonTestTemplates(self, result, filename): def _ParsePythonTestTemplates(self, result, filename):
pathname = join(self.root, filename + ".pyt") pathname = os.path.join(self.root, filename + ".pyt")
def Test(name, source, expectation): def Test(name, source, expectation):
source = source.replace("\n", " ") source = source.replace("\n", " ")
testname = os.path.join(filename, name) testname = os.path.join(filename, name)
@ -118,143 +118,3 @@ class PreparserTestSuite(testsuite.TestSuite):
def GetSuite(name, root): def GetSuite(name, root):
return PreparserTestSuite(name, root) return PreparserTestSuite(name, root)
# Deprecated definitions below.
# TODO(jkummerow): Remove when SCons is no longer supported.
from os.path import join, exists, isfile
import test
class PreparserTestCase(test.TestCase):
def __init__(self, root, path, executable, mode, throws, context, source):
super(PreparserTestCase, self).__init__(context, path, mode)
self.executable = executable
self.root = root
self.throws = throws
self.source = source
def GetLabel(self):
return "%s %s %s" % (self.mode, self.path[-2], self.path[-1])
def GetName(self):
return self.path[-1]
def HasSource(self):
return self.source is not None
def GetSource(self):
return self.source
def BuildCommand(self, path):
if (self.source is not None):
result = [self.executable, "-e", self.source]
else:
testfile = join(self.root, self.GetName()) + ".js"
result = [self.executable, testfile]
if (self.throws):
result += ['throws'] + self.throws
return result
def GetCommand(self):
return self.BuildCommand(self.path)
def Run(self):
return test.TestCase.Run(self)
class PreparserTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(PreparserTestConfiguration, self).__init__(context, root)
def GetBuildRequirements(self):
return ['preparser']
def GetExpectations(self):
expects_file = join(self.root, 'preparser.expectation')
map = {}
if exists(expects_file):
rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$")
for line in utils.ReadLinesFrom(expects_file):
if (line[0] == '#'): continue
rule_match = rule_regex.match(line)
if rule_match:
expects = []
if (rule_match.group(2)):
expects = expects + [rule_match.group(2)]
if (rule_match.group(3)):
expects = expects + [rule_match.group(3), rule_match.group(4)]
map[rule_match.group(1)] = expects
return map;
def ParsePythonTestTemplates(self, result, filename,
executable, current_path, mode):
pathname = join(self.root, filename + ".pyt")
def Test(name, source, expectation):
throws = None
if (expectation is not None):
throws = [expectation]
test = PreparserTestCase(self.root,
current_path + [filename, name],
executable,
mode, throws, self.context,
source.replace("\n", " "))
result.append(test)
def Template(name, source):
def MkTest(replacement, expectation):
testname = name
testsource = source
for key in replacement.keys():
testname = testname.replace("$"+key, replacement[key]);
testsource = testsource.replace("$"+key, replacement[key]);
Test(testname, testsource, expectation)
return MkTest
execfile(pathname, {"Test": Test, "Template": Template})
def ListTests(self, current_path, path, mode, variant_flags):
executable = 'preparser'
if utils.IsWindows():
executable += '.exe'
executable = join(self.context.buildspace, executable)
if not isfile(executable):
executable = join('obj', 'preparser', mode, 'preparser')
if utils.IsWindows():
executable += '.exe'
executable = join(self.context.buildspace, executable)
expectations = self.GetExpectations()
result = []
# Find all .js files in tests/preparser directory.
filenames = [f[:-3] for f in os.listdir(self.root) if f.endswith(".js")]
filenames.sort()
for file in filenames:
throws = None;
if (file in expectations):
throws = expectations[file]
result.append(PreparserTestCase(self.root,
current_path + [file], executable,
mode, throws, self.context, None))
# Find all .pyt files in test/preparser directory.
filenames = [f[:-4] for f in os.listdir(self.root) if f.endswith(".pyt")]
filenames.sort()
for file in filenames:
# Each file as a python source file to be executed in a specially
# created environment (defining the Template and Test functions)
self.ParsePythonTestTemplates(result, file,
executable, current_path, mode)
return result
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'preparser.status')
if exists(status_file):
test.ReadConfigurationInto(status_file, sections, defs)
def VariantFlags(self):
return [[]];
def GetConfiguration(context, root):
return PreparserTestConfiguration(context, root)

6
deps/v8/test/sputnik/README

@ -1,6 +0,0 @@
To run the sputniktests you must check out the test suite from
googlecode.com. The test expectations are currently relative to
version 97. To get the tests run the following command within
v8/test/sputnik/
svn co http://sputniktests.googlecode.com/svn/trunk/ -r97 sputniktests

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save