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
/out
/test/cctest/cctest.status2
/test/es5conform/data
/test/message/message.status2
/test/mjsunit/mjsunit.status2
/test/mozilla/CHECKED_OUT_VERSION
@ -37,7 +36,6 @@ shell_g
/test/mozilla/downloaded_*
/test/mozilla/mozilla.status2
/test/preparser/preparser.status2
/test/sputnik/sputniktests
/test/test262/data
/test/test262/test262-*
/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
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" \
or OS=="android"', {
'cflags!': [
'-O2',
'-Os',
],
'cflags': [
'-fdata-sections',
'-ffunction-sections',
'-O3',
],
'conditions': [
[ 'gcc_version==44 and clang==0', {
'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;
LOG_API(isolate, "Persistent::New");
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
#ifdef DEBUG
(*obj)->Verify();
#endif // DEBUG
return result.location();
}

21
deps/v8/src/arguments.h

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

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

@ -266,19 +266,11 @@ Object** RelocInfo::call_object_address() {
bool RelocInfo::IsPatchedReturnSequence() {
Instr current_instr = Assembler::instr_at(pc_);
Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize);
#ifdef USE_BLX
// A patched return sequence is:
// ldr ip, [pc, #0]
// blx ip
return ((current_instr & kLdrPCMask) == kLdrPCPattern)
&& ((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);
}
#ifdef USE_BLX
// If we have a blx instruction, the instruction before it is
// what needs to be patched.
// With a blx instruction, the instruction before is what needs to be patched.
if ((instr & kBlxRegMask) == kBlxRegPattern) {
target_pc -= kInstrSize;
instr = Memory::int32_at(target_pc);
}
#endif
ASSERT(IsLdrPcImmediateOffset(instr));
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) {
// Returns the address of the call target from the return address that will
// be returned to after a call.
#ifdef USE_BLX
// Call sequence on V7 or later is :
// movw ip, #... @ call address low 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)) &&
IsMovT(Memory::int32_at(candidate + kInstrSize)));
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) {
#ifdef USE_BLX
if (IsLdrPcImmediateOffset(Memory::int32_at(pc))) {
return pc + kInstrSize * 2;
} else {
@ -480,9 +460,6 @@ Address Assembler::return_address_from_call_start(Address pc) {
ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
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));
}
#else // def __arm__
#ifdef CAN_USE_ARMV5_INSTRUCTIONS
if (cond != al) {
Label skip;
b(&skip, NegateCondition(cond));
@ -1692,9 +1691,6 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) {
} else {
bkpt(0);
}
#else // ndef CAN_USE_ARMV5_INSTRUCTIONS
svc(0x9f0001, cond);
#endif // ndef CAN_USE_ARMV5_INSTRUCTIONS
#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
// to jump to.
#ifdef USE_BLX
// Patched return sequence is:
// ldr ip, [pc, #0] @ emited address and start
// blx ip
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
// to jump to.
#ifdef USE_BLX
// Patched debug break slot code is:
// ldr ip, [pc, #0] @ emited address and start
// blx ip
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;
#else
static const int kPatchDebugBreakSlotReturnOffset = kInstrSize;
#endif
// Difference between address of current opcode and value read from pc
// register.
@ -1130,16 +1112,8 @@ class Assembler : public AssemblerBase {
static bool use_immediate_embedded_pointer_loads(
const Assembler* assembler) {
#ifdef USE_BLX
return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
(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.

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

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

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

@ -130,7 +130,7 @@ class UnaryOpStub: public PlatformCodeStub {
void GenerateGenericStubBitNot(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() {
return UnaryOpIC::ToState(operand_type_);

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

@ -33,13 +33,6 @@
#error ARM EABI support is required.
#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__) || \
defined(__ARM_ARCH_7R__) || \
defined(__ARM_ARCH_7__)
@ -49,39 +42,11 @@
#endif
#endif
#if defined(__ARM_ARCH_6__) || \
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.
// Simulator should support unaligned access by default.
#if !defined(__arm__)
# define CAN_USE_ARMV5_INSTRUCTIONS 1
# define CAN_USE_THUMB_INSTRUCTIONS 1
# ifndef CAN_USE_UNALIGNED_ACCESSES
# define CAN_USE_UNALIGNED_ACCESSES 1
# 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
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() {
#if !defined (__arm__) || !defined(CAN_USE_ARMV5_INSTRUCTIONS)
#if !defined (__arm__)
UNIMPLEMENTED(); // when building ARM emulator target
#else
asm volatile("bkpt 0");

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

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

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

@ -3976,18 +3976,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
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:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
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();
for (int i = 0; i < block->phis()->length(); ++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) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
if (block->deleted_phis()->at(i) < last_environment->length()) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
}
block->UpdateEnvironment(last_environment);
// 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];
__ bind(code->entry());
if (NeedsDeferredFrame()) {
Comment(";;; Deferred build frame",
Comment(";;; Deferred build frame @%d: %s.",
code->instruction_index(),
code->instr()->Mnemonic());
ASSERT(!frame_is_built_);
@ -320,7 +320,7 @@ bool LCodeGen::GenerateDeferredCode() {
code->instr()->Mnemonic());
code->Generate();
if (NeedsDeferredFrame()) {
Comment(";;; Deferred destroy frame",
Comment(";;; Deferred destroy frame @%d: %s.",
code->instruction_index(),
code->instr()->Mnemonic());
ASSERT(frame_is_built_);
@ -1043,11 +1043,9 @@ void LCodeGen::RecordPosition(int position) {
void LCodeGen::DoLabel(LLabel* label) {
if (label->is_loop_header()) {
Comment(";;; B%d - LOOP entry", label->block_id());
} else {
Comment(";;; B%d", label->block_id());
}
Comment(";;; -------------------- B%d%s --------------------",
label->block_id(),
label->is_loop_header() ? " (loop header)" : "");
__ bind(label->label());
current_block_ = label->block_id();
DoGap(label);
@ -2055,33 +2053,38 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
HMathMinMax::Operation operation = instr->hydrogen()->operation();
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
if (instr->hydrogen()->representation().IsInteger32()) {
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
Register left_reg = ToRegister(left);
Operand right_op = (right->IsRegister() || right->IsConstantOperand())
? ToOperand(right)
: Operand(EmitLoadRegister(right, ip));
Register result_reg = ToRegister(instr->result());
__ cmp(left_reg, right_op);
if (!result_reg.is(left_reg)) {
__ mov(result_reg, left_reg, LeaveCC, condition);
}
__ Move(result_reg, left_reg, condition);
__ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
} else {
ASSERT(instr->hydrogen()->representation().IsDouble());
DwVfpRegister left_reg = ToDoubleRegister(left);
DwVfpRegister right_reg = ToDoubleRegister(right);
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);
__ b(vs, &check_nan_left);
__ b(eq, &check_zero);
__ b(condition, &return_left);
__ b(al, &return_right);
__ bind(&check_zero);
if (operation == HMathMinMax::kMathMin) {
__ b(mi, &return_left);
__ b(gt, &return_right);
} else {
__ b(mi, &return_right);
__ b(gt, &return_left);
}
__ b(vs, &result_is_nan);
// Left equals right => check for -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.
if (operation == HMathMinMax::kMathMin) {
// 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.
__ 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);
if (!right_reg.is(result_reg)) {
__ vmov(result_reg, right_reg);
__ Move(result_reg, right_reg);
if (!left_reg.is(result_reg)) {
__ b(&done);
}
__ b(al, &done);
__ bind(&return_left);
if (!left_reg.is(result_reg)) {
__ vmov(result_reg, left_reg);
}
__ Move(result_reg, left_reg);
__ bind(&done);
}
}
@ -2205,12 +2208,10 @@ void LCodeGen::DoBranch(LBranch* instr) {
EmitBranch(true_block, false_block, ne);
} else if (r.IsDouble()) {
DwVfpRegister reg = ToDoubleRegister(instr->value());
Register scratch = scratch0();
// Test the double value. Zero and NaN are false.
__ VFPCompareAndLoadFlags(reg, 0.0, scratch);
__ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
EmitBranch(true_block, false_block, eq);
__ VFPCompareAndSetFlags(reg, 0.0);
__ cmp(r0, r0, vs); // If NaN, set the Z flag.
EmitBranch(true_block, false_block, ne);
} else {
ASSERT(r.IsTagged());
Register reg = ToRegister(instr->value());
@ -2302,7 +2303,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ b(ne, &not_heap_number);
__ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
__ 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(true_label);
__ bind(&not_heap_number);

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

@ -29,10 +29,12 @@
#define V8_ARM_LITHIUM_CODEGEN_ARM_H_
#include "arm/lithium-arm.h"
#include "arm/lithium-gap-resolver-arm.h"
#include "deoptimizer.h"
#include "safepoint-table.h"
#include "scopes.h"
#include "v8utils.h"
namespace v8 {
namespace internal {
@ -211,7 +213,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
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()); }

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) {
#if USE_BX
bx(target, cond);
#else
mov(pc, Operand(target), LeaveCC, cond);
#endif
}
void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode,
Condition cond) {
#if USE_BX
mov(ip, Operand(target, rmode));
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) {
#ifdef USE_BLX
return kInstrSize;
#else
return 2 * kInstrSize;
#endif
}
@ -121,13 +88,7 @@ void MacroAssembler::Call(Register target, Condition cond) {
BlockConstPoolScope block_const_pool(this);
Label start;
bind(&start);
#ifdef USE_BLX
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));
}
@ -170,7 +131,6 @@ void MacroAssembler::Call(Address target,
set_predictable_code_size(true);
}
#ifdef USE_BLX
// Call sequence on V7 or later may be :
// movw ip, #... @ call address low 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));
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));
if (mode == NEVER_INLINE_TARGET_ADDRESS) {
set_predictable_code_size(old_predictable_code_size);
@ -230,11 +184,7 @@ void MacroAssembler::Call(Handle<Code> code,
void MacroAssembler::Ret(Condition cond) {
#if USE_BX
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) {
mov(scratch, Operand(ExternalReference::cpu_features()));
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_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
// Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise.
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
// or one integer arguments. All are constructed here,
// For use in calls that take two double values, constructed either
// 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()) {
*x = vfp_registers_[0];
*y = vfp_registers_[1];
*z = 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.
@ -993,9 +991,41 @@ void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
// Registers 2 and 3 -> y.
OS::MemCopy(buffer, registers_ + 2, 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 arg4,
int32_t arg5);
// These prototypes handle the four types of FP calls.
typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
typedef double (*SimulatorRuntimeFPCall)(double darg0);
typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
int32_t arg1,
int32_t arg2,
int32_t arg3);
// This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h).
@ -1689,27 +1717,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
intptr_t external =
reinterpret_cast<intptr_t>(redirection->external_function());
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) {
SimulatorRuntimeCall generic_target =
reinterpret_cast<SimulatorRuntimeCall>(external);
SimulatorRuntimeFPCall target =
reinterpret_cast<SimulatorRuntimeFPCall>(external);
double dval0, dval1;
int32_t ival;
switch (redirection->type()) {
case ExternalReference::BUILTIN_FP_FP_CALL:
case ExternalReference::BUILTIN_COMPARE_CALL:
GetFpArgs(&dval0, &dval1);
PrintF("Call to host function at %p with args %f, %f",
FUNCTION_ADDR(generic_target), dval0, dval1);
FUNCTION_ADDR(target), dval0, dval1);
break;
case ExternalReference::BUILTIN_FP_CALL:
GetFpArgs(&dval0);
PrintF("Call to host function at %p with arg %f",
FUNCTION_ADDR(generic_target), dval0);
FUNCTION_ADDR(target), dval0);
break;
case ExternalReference::BUILTIN_FP_INT_CALL:
GetFpArgs(&dval0, &ival);
PrintF("Call to host function at %p with args %f, %d",
FUNCTION_ADDR(generic_target), dval0, ival);
FUNCTION_ADDR(target), dval0, ival);
break;
default:
UNREACHABLE();
@ -1721,54 +1749,22 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
PrintF("\n");
}
CHECK(stack_aligned);
switch (redirection->type()) {
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: {
if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) {
SimulatorRuntimeFPCall target =
reinterpret_cast<SimulatorRuntimeFPCall>(external);
dresult = target(dval0);
SetFpResult(dresult);
break;
}
case ExternalReference::BUILTIN_FP_INT_CALL: {
SimulatorRuntimeFPIntCall target =
reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
dresult = target(dval0, ival);
SetFpResult(dresult);
break;
}
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;
reinterpret_cast<SimulatorRuntimeFPCall>(external);
double result = target(arg0, arg1, arg2, arg3);
SetFpResult(result);
} else {
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
int32_t lo_res = static_cast<int32_t>(result);
int32_t hi_res = static_cast<int32_t>(result >> 32);
if (::v8::internal::FLAG_trace_sim) {
PrintF("Returned %08x\n", lo_res);
}
set_register(r0, lo_res);
set_register(r1, hi_res);
}
} else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
SimulatorRuntimeDirectApiCall target =

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

@ -348,8 +348,10 @@ class Simulator {
void* external_function,
v8::internal::ExternalReference::Type type);
// Handle arguments and return value for runtime FP functions.
void GetFpArgs(double* x, double* y, int32_t* z);
// For use in calls that take double value arguments.
void GetFpArgs(double* x, double* y);
void GetFpArgs(double* x);
void GetFpArgs(double* x, int32_t* y);
void SetFpResult(const double& result);
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;
}
#if defined(__x86_64__) && defined(V8_HOST_ARCH_64_BIT)
#if defined(__x86_64__)
// 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
#define BUILTIN(name) \
MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate); \
MUST_USE_RESULT static MaybeObject* Builtin_##name( \
int args_length, Object** args_object, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \
ASSERT(isolate == Isolate::Current()); \
args.Verify(); \
return Builtin_Impl_##name(args, isolate); \
} \
MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
#define BUILTIN(name) \
MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate); \
MUST_USE_RESULT static MaybeObject* Builtin_##name( \
name##ArgumentsType args, Isolate* isolate) { \
ASSERT(isolate == Isolate::Current()); \
args.Verify(); \
return Builtin_Impl_##name(args, isolate); \
} \
MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate)
#else // For release mode.
#define BUILTIN(name) \
static MaybeObject* Builtin_impl##name( \
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)
#define BUILTIN(name) \
static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate)
#endif

2
deps/v8/src/builtins.h

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

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

@ -106,8 +106,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
Zone* zone = this->zone();
int param_count = descriptor_->register_param_count_;
HEnvironment* start_environment = graph()->start_environment();
HBasicBlock* next_block =
CreateBasicBlock(start_environment, BailoutId::StubEntry());
HBasicBlock* next_block = CreateBasicBlock(start_environment);
current_block()->Goto(next_block);
next_block->SetJoinId(BailoutId::StubEntry());
set_current_block(next_block);
@ -186,7 +185,7 @@ template <class Stub>
static Handle<Code> DoGenerateCode(Stub* stub) {
CodeStubGraphBuilder<Stub> builder(stub);
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));
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(),
boilerplate,
alloc_site_mode,
FAST_ELEMENTS,
0/*copy-on-write*/));
if_fixed_cow.BeginElse();
if_fixed_cow.Else();
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(),
boilerplate,
alloc_site_mode,
FAST_ELEMENTS,
length));
if_fixed.BeginElse();
if_fixed.Else();
environment()->Push(BuildCloneShallowArray(context(),
boilerplate,
alloc_site_mode,
@ -250,7 +250,7 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
CodeStubGraphBuilder<FastCloneShallowArrayStub> builder(this);
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);
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.
if_builder.BeginElse();
if_builder.Else();
HInstruction* elements =
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;
}
@ -98,7 +98,7 @@ Handle<Code> PlatformCodeStub::GenerateCode() {
// Copy the generated code into a heap object.
Code::Flags flags = Code::ComputeFlags(
static_cast<Code::Kind>(GetCodeKind()),
GetCodeKind(),
GetICState(),
GetExtraICState(),
GetStubType(),
@ -308,7 +308,7 @@ void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
Factory* factory = isolate->factory();
Code::Flags flags = Code::ComputeFlags(
static_cast<Code::Kind>(GetCodeKind()),
GetCodeKind(),
UNINITIALIZED);
ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT);
Handle<Object> probe(

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

@ -176,19 +176,19 @@ class CodeStub BASE_EMBEDDED {
virtual Major MajorKey() = 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() {
return UNINITIALIZED;
}
virtual Code::ExtraICState GetExtraICState() {
return Code::kNoExtraICState;
}
protected:
static bool CanUseFPRegisters();
// Generates the assembler code for the stub.
virtual Handle<Code> GenerateCode() = 0;
virtual Code::StubType GetStubType() {
return Code::NORMAL;
}
@ -210,7 +210,7 @@ class CodeStub BASE_EMBEDDED {
virtual void Activate(Code* code) { }
// BinaryOpStub needs to override this.
virtual int GetCodeKind();
virtual Code::Kind GetCodeKind() const;
// Add the code to a specialized cache, specific to an individual
// 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.
virtual Handle<Code> GenerateCode();
virtual int GetCodeKind() { return Code::STUB; }
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
virtual int GetStubFlags() { return -1; }
protected:
@ -286,7 +286,7 @@ class HydrogenCodeStub : public CodeStub {
// Retrieve the code for the stub. Generate the code if needed.
virtual Handle<Code> GenerateCode() = 0;
virtual int GetCodeKind() { return Code::COMPILED_STUB; }
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate) {
return isolate->code_stub_interface_descriptor(MajorKey());
@ -606,7 +606,7 @@ class MathPowStub: public PlatformCodeStub {
class ICStub: public PlatformCodeStub {
public:
explicit ICStub(Code::Kind kind) : kind_(kind) { }
virtual int GetCodeKind() { return kind_; }
virtual Code::Kind GetCodeKind() const { return kind_; }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
bool Describes(Code* code) {
@ -692,7 +692,7 @@ class StoreArrayLengthStub: public StoreICStub {
class HandlerStub: public ICStub {
public:
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(); }
};
@ -830,7 +830,7 @@ class BinaryOpStub: public PlatformCodeStub {
// Entirely platform-specific methods are defined as static helper
// 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() {
return BinaryOpIC::ToState(Max(left_type_, right_type_));
@ -884,7 +884,7 @@ class ICCompareStub: public PlatformCodeStub {
virtual CodeStub::Major MajorKey() { return CompareIC; }
virtual int MinorKey();
virtual int GetCodeKind() { return Code::COMPARE_IC; }
virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; }
void GenerateSmis(MacroAssembler* masm);
void GenerateNumbers(MacroAssembler* masm);
@ -1548,7 +1548,7 @@ class ToBooleanStub: public PlatformCodeStub {
: tos_(tos), types_(types) { }
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 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.
CodeDesc desc;
bool is_crankshafted =
Code::ExtractKindFromFlags(flags) == Code::OPTIMIZED_FUNCTION ||
info->IsStub();
masm->GetCode(&desc);
Handle<Code> code =
isolate->factory()->NewCode(desc, flags, masm->CodeObject());
isolate->factory()->NewCode(desc, flags, masm->CodeObject(),
false, is_crankshafted);
if (!code.is_null()) {
isolate->counters()->total_compiled_code_size()->Increment(
code->instruction_size());
@ -129,7 +132,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
if (print_code) {
// Print the source code if available.
FunctionLiteral* function = info->function();
if (code->kind() != Code::COMPILED_STUB) {
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
Handle<Script> script = info->script();
if (!script->IsUndefined() && !script->source()->IsUndefined()) {
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 {
if (IsStub()) {
return Code::ComputeFlags(Code::COMPILED_STUB);
return Code::ComputeFlags(code_stub()->GetCodeKind(),
code_stub()->GetICState(),
code_stub()->GetExtraICState(),
Code::NORMAL,
0);
} else {
return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
}
@ -421,7 +425,7 @@ OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() {
Timer timer(this, &time_taken_to_codegen_);
ASSERT(chunk_ != NULL);
ASSERT(graph_ != NULL);
Handle<Code> optimized_code = chunk_->Codegen(Code::OPTIMIZED_FUNCTION);
Handle<Code> optimized_code = chunk_->Codegen();
if (optimized_code.is_null()) {
info()->set_bailout_reason("code generation failed");
return AbortOptimization();
@ -553,6 +557,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
isolate->factory()->NewSharedFunctionInfo(
lit->name(),
lit->materialized_literal_count(),
lit->is_generator(),
info->code(),
ScopeInfo::Create(info->scope(), info->zone()));
@ -1074,6 +1079,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
Handle<SharedFunctionInfo> result =
FACTORY->NewSharedFunctionInfo(literal->name(),
literal->materialized_literal_count(),
literal->is_generator(),
info.code(),
scope_info);
SetFunctionInfo(result, literal, false, script);

2
deps/v8/src/compiler.h

@ -79,7 +79,7 @@ class CompilationInfo {
Handle<JSFunction> closure() const { return closure_; }
Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
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_; }
ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
Handle<Context> context() const { return context_; }

5
deps/v8/src/deoptimizer.cc

@ -1195,7 +1195,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// 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();
CodeStubInterfaceDescriptor* descriptor =
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
// environment at the OSR entry. The code for that his built into
// 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 outgoing_size = ComputeOutgoingArgumentSize();
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.
void Disassembler::Decode(FILE* f, Code* code) {
Isolate* isolate = code->GetIsolate();
int decode_size = (code->kind() == Code::OPTIMIZED_FUNCTION ||
code->kind() == Code::COMPILED_STUB)
int decode_size = code->is_crankshafted()
? static_cast<int>(code->safepoint_table_offset())
: code->instruction_size();
// 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
// modification, are permitted provided that the following conditions are
// met:
@ -916,10 +916,11 @@ Handle<JSObject> Factory::NewExternal(void* value) {
Handle<Code> Factory::NewCode(const CodeDesc& desc,
Code::Flags flags,
Handle<Object> self_ref,
bool immovable) {
bool immovable,
bool crankshafted) {
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->CreateCode(
desc, flags, self_ref, immovable),
desc, flags, self_ref, immovable, crankshafted),
Code);
}
@ -1078,6 +1079,7 @@ void Factory::SetIdentityHash(Handle<JSObject> object, Smi* hash) {
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name,
int number_of_literals,
bool is_generator,
Handle<Code> code,
Handle<ScopeInfo> scope_info) {
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
@ -1091,6 +1093,9 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
literals_array_size += JSFunction::kLiteralsPrefixSize;
}
shared->set_num_literals(literals_array_size);
if (is_generator) {
shared->set_instance_class_name(isolate()->heap()->Generator_string());
}
return shared;
}

4
deps/v8/src/factory.h

@ -347,7 +347,8 @@ class Factory {
Handle<Code> NewCode(const CodeDesc& desc,
Code::Flags flags,
Handle<Object> self_reference,
bool immovable = false);
bool immovable = false,
bool crankshafted = false);
Handle<Code> CopyCode(Handle<Code> code);
@ -454,6 +455,7 @@ class Factory {
Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name,
int number_of_literals,
bool is_generator,
Handle<Code> code,
Handle<ScopeInfo> scope_info);
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
function GeneratorObjectNext() {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.next', this]);
}
// TODO(wingo): Implement.
}
function GeneratorObjectSend(value) {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.send', this]);
}
// TODO(wingo): Implement.
}
function GeneratorObjectThrow(exn) {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.throw', this]);
}
// TODO(wingo): Implement.
}
function GeneratorObjectClose() {
if (!IS_GENERATOR(this)) {
throw MakeTypeError('incompatible_method_receiver',
['[Generator].prototype.close', this]);
}
// 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)
#define CALL_HEAP_FUNCTION_PASS_EXCEPTION(ISOLATE, FUNCTION_CALL) \
CALL_AND_RETRY(ISOLATE, \
FUNCTION_CALL, \
return __object__, \
return __maybe_object__)
#ifdef DEBUG
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,
Code::Flags flags,
Handle<Object> self_reference,
bool immovable) {
bool immovable,
bool crankshafted) {
// Allocate ByteArray before the Code object, so that we do not risk
// leaving uninitialized Code object (and breaking the heap).
ByteArray* reloc_info;
@ -3796,6 +3797,7 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
if (code->is_call_stub() || code->is_keyed_call_stub()) {
code->set_check_type(RECEIVER_MAP_CHECK);
}
code->set_is_crankshafted(crankshafted);
code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
code->InitializeTypeFeedbackInfoNoWriteBarrier(undefined_value());
code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
@ -4358,6 +4360,7 @@ MaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) {
MaybeObject* maybe_map = AllocateInitialMap(function);
if (!maybe_map->To(&map)) return maybe_map;
function->set_initial_map(map);
map->set_constructor(function);
}
ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
return AllocateJSObjectFromMap(map);

6
deps/v8/src/heap.h

@ -268,7 +268,8 @@ namespace internal {
V(infinity_string, "Infinity") \
V(minus_infinity_string, "-Infinity") \
V(hidden_stack_trace_string, "v8::hidden_stack_trace") \
V(query_colon_string, "(?:)")
V(query_colon_string, "(?:)") \
V(Generator_string, "Generator")
// Forward declarations.
class GCTracer;
@ -1141,7 +1142,8 @@ class Heap {
MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc,
Code::Flags flags,
Handle<Object> self_reference,
bool immovable = false);
bool immovable = false,
bool crankshafted = false);
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) {
RegisterUse(index, value);
InternalSetOperandAt(index, value);
@ -1393,15 +1398,11 @@ HValue* HBitwise::Canonicalize() {
if (!representation().IsInteger32()) return this;
// 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;
if (left()->IsConstant() &&
HConstant::cast(left())->HasInteger32Value() &&
HConstant::cast(left())->Integer32Value() == nop_constant &&
if (left()->EqualsInteger32Constant(nop_constant) &&
!right()->CheckFlag(kUint32)) {
return right();
}
if (right()->IsConstant() &&
HConstant::cast(right())->HasInteger32Value() &&
HConstant::cast(right())->Integer32Value() == nop_constant &&
if (right()->EqualsInteger32Constant(nop_constant) &&
!left()->CheckFlag(kUint32)) {
return left();
}
@ -1422,17 +1423,37 @@ HValue* HBitNot::Canonicalize() {
}
HValue* HAdd::Canonicalize() {
if (!representation().IsInteger32()) return this;
if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow);
HValue* HArithmeticBinaryOperation::Canonicalize() {
if (representation().IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) {
ClearFlag(kCanOverflow);
}
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() {
if (!representation().IsInteger32()) return this;
if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow);
return this;
if (IsIdentityOperation(left(), right(), 0)) return left();
return HArithmeticBinaryOperation::Canonicalize();
}
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();
int32_t GetInteger32Constant();
bool EqualsInteger32Constant(int32_t value);
bool IsDefinedAfter(HBasicBlock* other) const;
@ -3328,10 +3329,6 @@ class HConstant: public HTemplateInstruction<0> {
bool BooleanValue() const { return boolean_value_; }
bool IsUint32() {
return HasInteger32Value() && (Integer32Value() >= 0);
}
virtual intptr_t Hashcode() {
if (has_int32_value_) {
return static_cast<intptr_t>(int32_value_);
@ -3842,6 +3839,8 @@ class HArithmeticBinaryOperation: public HBinaryOperation {
: representation();
}
virtual HValue* Canonicalize();
private:
virtual bool IsDeletable() const { return true; }
};
@ -4401,6 +4400,8 @@ class HMul: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual HValue* Canonicalize();
// Only commutative if it is certain that not two objects are multiplicated.
virtual bool IsCommutative() const {
return !representation().IsTagged();

453
deps/v8/src/hydrogen.cc

@ -113,11 +113,10 @@ void HBasicBlock::AddInstruction(HInstruction* instr) {
ASSERT(!IsStartBlock() || !IsFinished());
ASSERT(!instr->IsLinked());
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) {
ASSERT(last_environment() != NULL);
ASSERT(!last_environment()->ast_id().IsNone());
HBlockEntry* entry = new(zone()) HBlockEntry();
entry->InitializeAsFirst(this);
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 &&
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);
}
AddSimulate(BailoutId::None());
if (add_simulate) AddSimulate(BailoutId::None());
HGoto* instr = new(zone()) HGoto(block);
Finish(instr);
}
@ -215,12 +216,10 @@ void HBasicBlock::AddLeaveInlined(HValue* return_value,
}
void HBasicBlock::SetInitialEnvironment(HEnvironment* env,
BailoutId previous_ast_id) {
void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
ASSERT(!HasEnvironment());
ASSERT(first() == NULL);
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()
->VerifyBailoutId(ast_id)));
simulate->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);
predecessor->last_environment()->set_ast_id(ast_id);
}
}
@ -301,9 +296,7 @@ void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
}
} else if (!HasEnvironment() && !IsFinished()) {
ASSERT(!IsLoopHeader());
HEnvironment* new_env = pred->last_environment()->Copy();
SetInitialEnvironment(new_env,
pred->last_environment()->previous_ast_id());
SetInitialEnvironment(pred->last_environment()->Copy());
}
predecessors_.Add(pred, zone());
@ -553,6 +546,18 @@ void HGraph::Verify(bool do_full_verify) const {
HPhi* phi = block->phis()->at(j);
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.
@ -639,25 +644,24 @@ DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder)
: builder_(builder),
finished_(false),
id_(builder->current_block()->last_environment()->previous_ast_id()) {
finished_(false) {
HEnvironment* env = builder->environment();
failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_);
merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_);
failure_block_ = builder->CreateBasicBlock(env->Copy());
merge_block_ = builder->CreateBasicBlock(env->Copy());
}
HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) {
HEnvironment* env = builder_->environment();
HIsNilAndBranch* compare =
new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue);
HBasicBlock* success_block =
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_);
HBasicBlock* failure_block =
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_);
HCompareObjectEqAndBranch* compare =
new(zone()) HCompareObjectEqAndBranch(
value,
builder_->graph()->GetConstantUndefined());
HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy());
HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy());
compare->SetSuccessorAt(0, failure_block);
compare->SetSuccessorAt(1, success_block);
failure_block->Goto(failure_block_);
failure_block->GotoNoSimulate(failure_block_);
builder_->current_block()->Finish(compare);
builder_->set_current_block(success_block);
return compare;
@ -671,13 +675,11 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left,
HCompareIDAndBranch* compare =
new(zone()) HCompareIDAndBranch(left, right, op);
compare->AssumeRepresentation(Representation::Integer32());
HBasicBlock* success_block =
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_);
HBasicBlock* failure_block =
builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_);
HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy());
HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy());
compare->SetSuccessorAt(0, success_block);
compare->SetSuccessorAt(1, failure_block);
failure_block->Goto(failure_block_);
failure_block->GotoNoSimulate(failure_block_);
builder_->current_block()->Finish(compare);
builder_->set_current_block(success_block);
return compare;
@ -692,11 +694,11 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left,
void HGraphBuilder::CheckBuilder::End() {
ASSERT(!finished_);
builder_->current_block()->Goto(merge_block_);
failure_block_->SetJoinId(id_);
failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
builder_->current_block()->GotoNoSimulate(merge_block_);
if (failure_block_->HasPredecessor()) {
failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
}
builder_->set_current_block(merge_block_);
merge_block_->SetJoinId(id_);
finished_ = true;
}
@ -706,19 +708,51 @@ HConstant* HGraph::GetInvalidContext() {
}
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder)
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
: builder_(builder),
position_(position),
finished_(false),
did_then_(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();
first_true_block_ = builder->CreateBasicBlock(env->Copy(), id_);
first_true_block_ = builder->CreateBasicBlock(env->Copy());
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* right,
Token::Value token,
@ -728,58 +762,148 @@ HInstruction* HGraphBuilder::IfBuilder::BeginIf(
compare->set_observed_input_representation(input_representation,
input_representation);
compare->ChangeRepresentation(input_representation);
compare->SetSuccessorAt(0, first_true_block_);
compare->SetSuccessorAt(1, first_false_block_);
builder_->current_block()->Finish(compare);
builder_->set_current_block(first_true_block_);
AddCompare(compare);
return compare;
}
HInstruction* HGraphBuilder::IfBuilder::BeginIfObjectsEqual(
HValue* left,
HValue* right) {
HCompareObjectEqAndBranch* compare =
new(zone()) HCompareObjectEqAndBranch(left, right);
compare->SetSuccessorAt(0, first_true_block_);
compare->SetSuccessorAt(1, first_false_block_);
builder_->current_block()->Finish(compare);
builder_->set_current_block(first_true_block_);
HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
Handle<Map> map) {
HCompareMap* compare =
new(zone()) HCompareMap(left, map,
first_true_block_, first_false_block_);
AddCompare(compare);
return compare;
}
HInstruction* HGraphBuilder::IfBuilder::BeginIfMapEquals(HValue* value,
Handle<Map> map) {
HCompareMap* compare = new(zone())
HCompareMap(value, map, first_true_block_, first_false_block_);
void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
if (split_edge_merge_block_ != NULL) {
HEnvironment* env = first_false_block_->last_environment();
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);
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_);
return compare;
}
void HGraphBuilder::IfBuilder::BeginElse() {
void HGraphBuilder::IfBuilder::Else() {
ASSERT(did_then_);
ASSERT(!captured_);
ASSERT(!finished_);
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_);
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() {
ASSERT(!finished_);
if (!did_else_) BeginElse();
ASSERT(!last_true_block_->IsFinished());
HBasicBlock* last_false_block = builder_->current_block();
ASSERT(!last_false_block->IsFinished());
HEnvironment* merge_env =
last_true_block_->last_environment()->CopyWithoutHistory();
merge_block_ = builder_->CreateBasicBlock(merge_env, id_);
last_true_block_->Goto(merge_block_);
last_false_block->Goto(merge_block_);
merge_block_->SetJoinId(id_);
builder_->set_current_block(merge_block_);
if (!captured_) {
ASSERT(did_then_);
if (!did_else_) {
last_true_block_ = builder_->current_block();
}
if (first_true_block_ == NULL) {
// Deopt on true. Nothing to do, just continue the else block.
} else if (first_false_block_ == NULL) {
builder_->set_current_block(last_true_block_);
} else {
HEnvironment* merge_env = last_true_block_->last_environment()->Copy();
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;
}
@ -790,9 +914,8 @@ HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
: builder_(builder),
context_(context),
direction_(direction),
id_(builder->current_block()->last_environment()->previous_ast_id()),
finished_(false) {
header_block_ = builder->CreateLoopHeaderBlock(id_);
header_block_ = builder->CreateLoopHeaderBlock();
body_block_ = NULL;
exit_block_ = NULL;
}
@ -809,12 +932,12 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody(
phi_->AddInput(initial);
phi_->ChangeRepresentation(Representation::Integer32());
env->Push(initial);
builder_->current_block()->Goto(header_block_);
builder_->current_block()->GotoNoSimulate(header_block_);
HEnvironment* body_env = env->Copy();
HEnvironment* exit_env = env->Copy();
body_block_ = builder_->CreateBasicBlock(body_env, id_);
exit_block_ = builder_->CreateBasicBlock(exit_env, id_);
body_block_ = builder_->CreateBasicBlock(body_env);
exit_block_ = builder_->CreateBasicBlock(exit_env);
// Remove the phi from the expression stack
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.
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_->SetJoinId(id_);
builder_->set_current_block(exit_block_);
// Pop the phi from the expression stack
@ -900,7 +1022,6 @@ void HGraphBuilder::AddSimulate(BailoutId id,
ASSERT(current_block() != NULL);
ASSERT(no_side_effects_scope_count_ == 0);
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,
BailoutId previous_ast_id) {
HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
HBasicBlock* b = graph()->CreateBasicBlock();
b->SetInitialEnvironment(env, previous_ast_id);
b->SetInitialEnvironment(env);
return b;
}
HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock(BailoutId previous_ast_id) {
HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
HBasicBlock* header = graph()->CreateBasicBlock();
HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
header->SetInitialEnvironment(entry_env, previous_ast_id);
header->SetInitialEnvironment(entry_env);
header->AttachLoopInformation();
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(
HValue* external_elements,
HValue* checked_key,
@ -1049,14 +1184,16 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
Zone* zone = this->zone();
IfBuilder length_checker(this);
length_checker.BeginIf(length, key, Token::EQ);
length_checker.IfCompare(length, key, Token::EQ);
length_checker.Then();
HValue* current_capacity =
AddInstruction(new(zone) HFixedArrayBaseLength(elements));
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();
@ -1068,7 +1205,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
new_capacity);
environment()->Push(new_elements);
capacity_checker.BeginElse();
capacity_checker.Else();
environment()->Push(elements);
capacity_checker.End();
@ -1088,7 +1225,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
length_store->SetGVNFlag(kChangesArrayLengths);
}
length_checker.BeginElse();
length_checker.Else();
AddBoundsCheck(key, length, ALLOW_SMI_KEY);
environment()->Push(elements);
@ -1108,19 +1245,19 @@ HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object,
IfBuilder cow_checker(this);
cow_checker.BeginIfMapEquals(elements,
Handle<Map>(heap->fixed_cow_array_map()));
cow_checker.IfCompareMap(elements,
Handle<Map>(heap->fixed_cow_array_map()));
cow_checker.Then();
HValue* capacity =
AddInstruction(new(zone) HFixedArrayBaseLength(elements));
HValue* new_elements = BuildGrowElementsCapacity(object, elements,
kind, length,
capacity);
kind, length, capacity);
environment()->Push(new_elements);
cow_checker.BeginElse();
cow_checker.Else();
environment()->Push(elements);
@ -1175,11 +1312,13 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
HValue* checked_key = NULL;
if (IsExternalArrayElementsKind(elements_kind)) {
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
NoObservableSideEffectsScope no_effects(this);
HLoadExternalArrayPointer* external_elements =
new(zone) HLoadExternalArrayPointer(elements);
AddInstruction(external_elements);
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);
HValue* bounds_check = negative_checker.CheckIntegerCompare(
key, graph()->GetConstant0(), Token::GTE);
@ -1216,7 +1355,11 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
elements = BuildCheckForCapacityGrow(object, elements, elements_kind,
length, key, is_js_array);
checked_key = key;
if (!key->type().IsSmi()) {
checked_key = AddInstruction(new(zone) HCheckSmiOrInt32(key));
} else {
checked_key = key;
}
} else {
checked_key = AddBoundsCheck(
key, length, ALLOW_SMI_KEY, checked_index_representation);
@ -1307,8 +1450,7 @@ void HGraphBuilder::BuildInitializeElements(HValue* elements,
HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
ElementsKind kind,
HValue* capacity) {
HValue* new_elements =
BuildAllocateElements(context, kind, capacity);
HValue* new_elements = BuildAllocateElements(context, kind, capacity);
BuildInitializeElements(new_elements, kind, capacity);
return new_elements;
}
@ -1684,9 +1826,9 @@ HGraph::HGraph(CompilationInfo* info)
start_environment_ =
new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
}
start_environment_->set_ast_id(BailoutId::FunctionEntry());
entry_block_ = CreateBasicBlock();
entry_block_->SetInitialEnvironment(start_environment_,
BailoutId::FunctionEntry());
entry_block_->SetInitialEnvironment(start_environment_);
}
@ -3839,8 +3981,8 @@ bool Uint32Analysis::CheckPhiOperands(HPhi* phi) {
HValue* operand = phi->OperandAt(j);
if (!operand->CheckFlag(HInstruction::kUint32)) {
// Lazyly mark constants that fit into uint32 range with kUint32 flag.
if (operand->IsConstant() &&
HConstant::cast(operand)->IsUint32()) {
if (operand->IsInteger32Constant() &&
operand->GetInteger32Constant() >= 0) {
operand->SetFlag(HInstruction::kUint32);
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) {
ASSERT(!instr->IsControlInstruction());
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) {
ASSERT(!instr->IsControlInstruction());
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) {
// 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
@ -4296,8 +4492,7 @@ bool HOptimizedGraphBuilder::BuildGraph() {
// values (but not instructions), present in the initial environment and
// not replayed by the Lithium translation.
HEnvironment* initial_env = environment()->CopyWithoutHistory();
HBasicBlock* body_entry = CreateBasicBlock(initial_env,
BailoutId::FunctionEntry());
HBasicBlock* body_entry = CreateBasicBlock(initial_env);
current_block()->Goto(body_entry);
body_entry->SetJoinId(BailoutId::FunctionEntry());
set_current_block(body_entry);
@ -5541,7 +5736,7 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId());
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(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() != NULL);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId());
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(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);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId());
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(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));
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId());
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
@ -6804,7 +6999,6 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
true, // is_store
&has_side_effects);
Push(value);
ASSERT(has_side_effects); // Stores always have side effects.
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
return ast_context()->ReturnValue(Pop());
}
@ -8279,7 +8473,6 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
AddSimulate(return_id);
current_block()->UpdateEnvironment(inner_env);
inner_env->set_previous_ast_id(BailoutId::FunctionEntry());
ZoneList<HValue*>* arguments_values = NULL;
// If the function uses arguments copy current arguments values
@ -8547,6 +8740,18 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
return true;
}
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:
if (!FLAG_fast_math) break;
// Fall through if FLAG_fast_math.
@ -8600,9 +8805,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
} else if (exponent == 2.0) {
result = HMul::New(zone(), context, left, left);
}
} else if (right->IsConstant() &&
HConstant::cast(right)->HasInteger32Value() &&
HConstant::cast(right)->Integer32Value() == 2) {
} else if (right->EqualsInteger32Constant(2)) {
result = HMul::New(zone(), context, left, left);
}
@ -9160,7 +9363,6 @@ void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
case Token::DELETE: return VisitDelete(expr);
case Token::VOID: return VisitVoid(expr);
case Token::TYPEOF: return VisitTypeof(expr);
case Token::ADD: return VisitAdd(expr);
case Token::SUB: return VisitSub(expr);
case Token::BIT_NOT: return VisitBitNot(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) {
CHECK_ALIVE(VisitForValue(expr->expression()));
HValue* value = Pop();
@ -11033,7 +11220,6 @@ HEnvironment::HEnvironment(HEnvironment* outer,
pop_count_(0),
push_count_(0),
ast_id_(BailoutId::None()),
previous_ast_id_(BailoutId::None()),
zone_(zone) {
Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0);
}
@ -11050,7 +11236,6 @@ HEnvironment::HEnvironment(Zone* zone, int parameter_count)
pop_count_(0),
push_count_(0),
ast_id_(BailoutId::None()),
previous_ast_id_(BailoutId::None()),
zone_(zone) {
Initialize(parameter_count, 0, 0);
}
@ -11067,7 +11252,6 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
pop_count_(0),
push_count_(0),
ast_id_(other->ast_id()),
previous_ast_id_(BailoutId::None()),
zone_(zone) {
Initialize(other);
}
@ -11088,7 +11272,6 @@ HEnvironment::HEnvironment(HEnvironment* outer,
pop_count_(0),
push_count_(0),
ast_id_(BailoutId::None()),
previous_ast_id_(BailoutId::None()),
zone_(zone) {
}

185
deps/v8/src/hydrogen.h

@ -108,7 +108,7 @@ class HBasicBlock: public ZoneObject {
bool Dominates(HBasicBlock* other) const;
int LoopNestingDepth() const;
void SetInitialEnvironment(HEnvironment* env, BailoutId previous_id);
void SetInitialEnvironment(HEnvironment* env);
void ClearEnvironment() { last_environment_ = NULL; }
bool HasEnvironment() const { return last_environment_ != NULL; }
void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
@ -125,7 +125,12 @@ class HBasicBlock: public ZoneObject {
void Finish(HControlInstruction* last);
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;
void AddSimulate(BailoutId ast_id,
@ -484,8 +489,6 @@ class HEnvironment: public ZoneObject {
BailoutId ast_id() const { return ast_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_; }
void set_entry(HEnterInlined* entry) { entry_ = entry; }
@ -647,7 +650,6 @@ class HEnvironment: public ZoneObject {
int pop_count_;
int push_count_;
BailoutId ast_id_;
BailoutId previous_ast_id_;
Zone* zone_;
};
@ -678,6 +680,9 @@ enum ArgumentsAllowedFlag {
ARGUMENTS_ALLOWED
};
class HIfContinuation;
// This class is not BASE_EMBEDDED because our inlining implementation uses
// new and delete.
class AstContext {
@ -703,6 +708,13 @@ class AstContext {
// expressions.
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; }
bool is_for_typeof() { return for_typeof_; }
@ -738,6 +750,8 @@ class EffectContext: public AstContext {
virtual void ReturnValue(HValue* value);
virtual void ReturnInstruction(HInstruction* 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 ReturnInstruction(HInstruction* 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; }
@ -776,6 +792,8 @@ class TestContext: public AstContext {
virtual void ReturnValue(HValue* value);
virtual void ReturnInstruction(HInstruction* 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) {
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 {
public:
explicit HGraphBuilder(CompilationInfo* info)
@ -906,9 +963,11 @@ class HGraphBuilder {
protected:
virtual bool BuildGraph() = 0;
HBasicBlock* CreateBasicBlock(HEnvironment* envy,
BailoutId previous_ast_id);
HBasicBlock* CreateLoopHeaderBlock(BailoutId previous_ast_id);
HBasicBlock* CreateBasicBlock(HEnvironment* env);
HBasicBlock* CreateLoopHeaderBlock();
HValue* BuildCheckNonSmi(HValue* object);
HValue* BuildCheckMap(HValue* obj, Handle<Map> map);
// Building common constructs
HInstruction* BuildExternalArrayElementAccess(
@ -973,37 +1032,127 @@ class HGraphBuilder {
bool finished_;
HBasicBlock* failure_block_;
HBasicBlock* merge_block_;
BailoutId id_;
};
class IfBuilder {
public:
explicit IfBuilder(HGraphBuilder* builder);
explicit IfBuilder(HGraphBuilder* builder,
int position = RelocInfo::kNoPosition);
IfBuilder(HGraphBuilder* builder,
HIfContinuation* continuation);
~IfBuilder() {
if (!finished_) End();
}
HInstruction* BeginIf(
HInstruction* IfCompare(
HValue* left,
HValue* right,
Token::Value token,
Representation input_representation = Representation::Integer32());
HInstruction* BeginIfObjectsEqual(HValue* left, HValue* right);
HInstruction* BeginIfMapEquals(HValue* value, Handle<Map> map);
void BeginElse();
HInstruction* IfCompareMap(HValue* left, Handle<Map> map);
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 Deopt();
private:
void AddCompare(HControlInstruction* compare);
Zone* zone() { return builder_->zone(); }
HGraphBuilder* builder_;
bool finished_;
bool did_else_;
int position_;
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* last_true_block_;
HBasicBlock* first_false_block_;
HBasicBlock* split_edge_merge_block_;
HBasicBlock* merge_block_;
BailoutId id_;
};
class LoopBuilder {
@ -1040,7 +1189,6 @@ class HGraphBuilder {
HBasicBlock* body_block_;
HBasicBlock* exit_block_;
Direction direction_;
BailoutId id_;
bool finished_;
};
@ -1267,7 +1415,6 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
void VisitDelete(UnaryOperation* expr);
void VisitVoid(UnaryOperation* expr);
void VisitTypeof(UnaryOperation* expr);
void VisitAdd(UnaryOperation* expr);
void VisitSub(UnaryOperation* expr);
void VisitBitNot(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)
#include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h"
#include "isolate.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 GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() {
return UnaryOpIC::ToState(operand_type_);

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

@ -3967,18 +3967,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
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:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break;

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

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

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

@ -32,9 +32,10 @@
#include "checks.h"
#include "deoptimizer.h"
#include "ia32/lithium-gap-resolver-ia32.h"
#include "safepoint-table.h"
#include "scopes.h"
#include "ia32/lithium-gap-resolver-ia32.h"
#include "v8utils.h"
namespace v8 {
namespace internal {
@ -201,7 +202,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
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()); }

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();
for (int i = 0; i < block->phis()->length(); ++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) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
if (block->deleted_phis()->at(i) < last_environment->length()) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
}
block->UpdateEnvironment(last_environment);
// Pick up the outgoing argument count of one of the predecessors.
@ -1693,7 +1697,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
HCompareObjectEqAndBranch* instr) {
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseAtStart(instr->right());
LOperand* right = UseOrConstantAtStart(instr->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());
}
return Runtime::SetObjectProperty(
return Runtime::SetObjectPropertyOrFail(
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);
LOG_CODE_EVENT(info()->isolate(),
CodeStartLinePosInfoRecordEvent(
@ -456,11 +456,11 @@ Handle<Code> LChunk::Codegen(Code::Kind kind) {
PrintF("Crankshaft Compiler - ");
}
CodeGenerator::MakeCodePrologue(info());
Code::Flags flags = Code::ComputeFlags(kind);
Code::Flags flags = info()->flags();
Handle<Code> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
generator.FinishCode(code);
code->set_is_crankshafted(true);
if (!code.is_null()) {
void* jit_handler_data =
assembler.positions_recorder()->DetachJITHandlerData();

2
deps/v8/src/lithium.h

@ -685,7 +685,7 @@ class LChunk: public ZoneObject {
Zone* zone() const { return info_->zone(); }
Handle<Code> Codegen(Code::Kind kind);
Handle<Code> Codegen();
void set_allocated_double_registers(BitVector* allocated_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::COMPARE_IC: // fall through
case Code::TO_BOOLEAN_IC: // fall through
case Code::COMPILED_STUB: // fall through
case Code::STUB:
description =
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_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === '__ArrayBuffer');
macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(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)
#include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h"
#include "codegen.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 GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() {
return UnaryOpIC::ToState(operand_type_);

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

@ -3995,19 +3995,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
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:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break;

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

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

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

@ -28,11 +28,12 @@
#ifndef 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 "mips/lithium-gap-resolver-mips.h"
#include "mips/lithium-mips.h"
#include "safepoint-table.h"
#include "scopes.h"
#include "v8utils.h"
namespace v8 {
namespace internal {
@ -207,7 +208,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
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()); }

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

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

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

3
deps/v8/src/objects.cc

@ -9313,7 +9313,6 @@ const char* Code::Kind2String(Kind kind) {
switch (kind) {
case FUNCTION: return "FUNCTION";
case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
case COMPILED_STUB: return "COMPILED_STUB";
case STUB: return "STUB";
case BUILTIN: return "BUILTIN";
case LOAD_IC: return "LOAD_IC";
@ -9613,7 +9612,7 @@ void Code::Disassemble(const char* name, FILE* out) {
}
PrintF("\n");
if (kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB) {
if (is_crankshafted()) {
SafepointTable table(this);
PrintF(out, "Safepoints (size = %u)\n", table.size());
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(OPTIMIZED_FUNCTION) \
V(STUB) \
V(COMPILED_STUB) \
V(BUILTIN) \
V(LOAD_IC) \
V(KEYED_LOAD_IC) \
@ -4470,6 +4469,11 @@ class Code: public HeapObject {
inline int major_key();
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
// called from other stubs.
inline bool is_pregenerated();
@ -4785,15 +4789,22 @@ class Code: public HeapObject {
kMarkedForDeoptimizationFirstBit,
kMarkedForDeoptimizationBitCount> {}; // NOLINT
// KindSpecificFlags2 layout (ALL)
static const int kIsCrankshaftedBit = 0;
class IsCrankshaftedField: public BitField<bool,
kIsCrankshaftedBit, 1> {}; // NOLINT
// KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
static const int kStubMajorKeyFirstBit = 0;
static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1;
static const int kSafepointTableOffsetFirstBit =
kStubMajorKeyFirstBit + kStubMajorKeyBits;
static const int kSafepointTableOffsetBitCount = 26;
static const int kSafepointTableOffsetBitCount = 25;
STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
STATIC_ASSERT(kSafepointTableOffsetFirstBit +
kSafepointTableOffsetBitCount <= 32);
STATIC_ASSERT(1 + kStubMajorKeyBits +
kSafepointTableOffsetBitCount <= 32);
class SafepointTableOffsetField: public BitField<int,
kSafepointTableOffsetFirstBit,
@ -4802,8 +4813,10 @@ class Code: public HeapObject {
kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT
// KindSpecificFlags2 layout (FUNCTION)
class BackEdgeTableOffsetField: public BitField<int, 0, 31> {};
class BackEdgesPatchedForOSRField: public BitField<bool, 31, 1> {};
class BackEdgeTableOffsetField: public BitField<int,
kIsCrankshaftedBit + 1, 29> {}; // NOLINT
class BackEdgesPatchedForOSRField: public BitField<bool,
kIsCrankshaftedBit + 1 + 29, 1> {}; // NOLINT
// Signed field cannot be encoded using the BitField class.
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();
Handle<Code> code = Handle<Code>(fun->shared()->code());
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
bool is_generator = false;
Handle<SharedFunctionInfo> shared =
isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
Handle<ScopeInfo>(fun->shared()->scope_info()));
isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
code, Handle<ScopeInfo>(fun->shared()->scope_info()));
shared->set_construct_stub(*construct_stub);
// 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);
} else if (Token::IsCountOp(op)) {

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

@ -194,9 +194,7 @@ void OS::Abort() {
void OS::DebugBreak() {
#if (defined(__arm__) || defined(__thumb__))
# if defined(CAN_USE_ARMV5_INSTRUCTIONS)
asm("bkpt 0");
# endif
#else
asm("int $3");
#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,
// which is the architecture of generated code).
#if (defined(__arm__) || defined(__thumb__))
# if defined(CAN_USE_ARMV5_INSTRUCTIONS)
asm("bkpt 0");
# endif
#elif defined(__mips__)
asm("break");
#elif defined(__native_client__)

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

@ -115,26 +115,11 @@ void* OS::GetRandomMmapAddr() {
raw_addr &= V8_UINT64_C(0x3ffffffff000);
#else
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
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
// 10.6 and 10.7.
raw_addr &= 0x3ffff000;
raw_addr += 0x20000000;
# endif
#endif
return reinterpret_cast<void*>(raw_addr);
}

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

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

38
deps/v8/src/runtime.cc

@ -706,9 +706,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
holder->set_byte_length(byte_length);
v8::Isolate* external_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Handle<Object> external_holder(*holder);
Persistent<Object> weak_handle = Persistent<Object>::New(
external_isolate, external_holder);
v8::Persistent<v8::Value> weak_handle = v8::Persistent<v8::Value>::New(
external_isolate, v8::Utils::ToLocal(Handle<Object>::cast(holder)));
weak_handle.MakeWeak(external_isolate, data, ArrayBufferWeakCallback);
weak_handle.MarkIndependent(external_isolate);
isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
@ -734,8 +733,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
size_t start = static_cast<size_t>(first);
size_t target_length = NumberToSize(isolate, target->byte_length());
if (target_length == 0)
return isolate->heap()->undefined_value();
if (target_length == 0) return isolate->heap()->undefined_value();
ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start);
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,
Object* char_code) {
uint32_t code;
if (char_code->ToArrayIndex(&code)) {
if (code <= 0xffff) {
return isolate->heap()->LookupSingleCharacterStringFromCode(code);
}
if (char_code->IsNumber()) {
return isolate->heap()->LookupSingleCharacterStringFromCode(
NumberToUint32(char_code) & 0xffff);
}
return isolate->heap()->empty_string();
}
@ -4096,6 +4092,13 @@ MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
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,
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,
Handle<Object> object,
Handle<Object> key,
@ -7636,7 +7651,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) {
ASSERT(args.length() == 0);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
ASSERT(isolate->heap()->IsAllocationAllowed());
ASSERT(deoptimizer->compiled_code_kind() == Code::COMPILED_STUB);
delete deoptimizer;
return isolate->heap()->undefined_value();
}
@ -7651,7 +7665,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
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.
JavaScriptFrameIterator it(isolate);

13
deps/v8/src/runtime.h

@ -702,6 +702,14 @@ class Runtime : public AllStatic {
PropertyAttributes attr,
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(
Isolate* isolate,
Handle<JSObject> object,
@ -725,6 +733,11 @@ class Runtime : public AllStatic {
Handle<Object> object,
Handle<Object> key);
MUST_USE_RESULT static MaybeObject* GetObjectPropertyOrFail(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key);
// Helper functions used stubs.
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) {
ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION ||
code->kind() == Code::COMPILED_STUB);
ASSERT(code->is_crankshafted());
code_ = code;
Address header = code->instruction_start() + code->safepoint_table_offset();
length_ = Memory::uint32_at(header + kLengthOffset);

1
deps/v8/src/spaces.cc

@ -1807,7 +1807,6 @@ static void ReportCodeKindStatistics() {
CASE(FUNCTION);
CASE(OPTIMIZED_FUNCTION);
CASE(STUB);
CASE(COMPILED_STUB);
CASE(BUILTIN);
CASE(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.
#define MAJOR_VERSION 3
#define MINOR_VERSION 18
#define BUILD_NUMBER 0
#define BUILD_NUMBER 1
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (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)
#include "bootstrapper.h"
#include "builtins-decls.h"
#include "code-stubs.h"
#include "regexp-macro-assembler.h"
#include "stub-cache.h"
@ -4273,10 +4272,6 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
Label invoke, handler_entry, exit;
Label not_outermost_js, not_outermost_js_2;
#ifdef _WIN64
const int kCalleeSaveXMMRegisters = 10;
const int kFullXMMRegisterSize = 16;
#endif
{ // NOLINT. Scope block confuses linter.
MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
// Set up frame.
@ -4306,17 +4301,17 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
#ifdef _WIN64
// On Win64 XMM6-XMM15 are callee-save
__ subq(rsp, Immediate(kCalleeSaveXMMRegisters * kFullXMMRegisterSize));
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 0), xmm6);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 1), xmm7);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 2), xmm8);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 3), xmm9);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 4), xmm10);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 5), xmm11);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 6), xmm12);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 7), xmm13);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 8), xmm14);
__ movdqu(Operand(rsp, kFullXMMRegisterSize * 9), xmm15);
__ subq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize));
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0), xmm6);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1), xmm7);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 2), xmm8);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 3), xmm9);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 4), xmm10);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 5), xmm11);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 6), xmm12);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 7), xmm13);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 8), xmm14);
__ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 9), xmm15);
#endif
// 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).
#ifdef _WIN64
// On Win64 XMM6-XMM15 are callee-save
__ movdqu(xmm6, Operand(rsp, kFullXMMRegisterSize * 0));
__ movdqu(xmm7, Operand(rsp, kFullXMMRegisterSize * 1));
__ movdqu(xmm8, Operand(rsp, kFullXMMRegisterSize * 2));
__ movdqu(xmm8, Operand(rsp, kFullXMMRegisterSize * 3));
__ movdqu(xmm10, Operand(rsp, kFullXMMRegisterSize * 4));
__ movdqu(xmm11, Operand(rsp, kFullXMMRegisterSize * 5));
__ movdqu(xmm12, Operand(rsp, kFullXMMRegisterSize * 6));
__ movdqu(xmm13, Operand(rsp, kFullXMMRegisterSize * 7));
__ movdqu(xmm14, Operand(rsp, kFullXMMRegisterSize * 8));
__ movdqu(xmm15, Operand(rsp, kFullXMMRegisterSize * 9));
__ addq(rsp, Immediate(kCalleeSaveXMMRegisters * kFullXMMRegisterSize));
__ movdqu(xmm6, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0));
__ movdqu(xmm7, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1));
__ movdqu(xmm8, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 2));
__ movdqu(xmm9, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 3));
__ movdqu(xmm10, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 4));
__ movdqu(xmm11, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 5));
__ movdqu(xmm12, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 6));
__ movdqu(xmm13, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 7));
__ movdqu(xmm14, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 8));
__ movdqu(xmm15, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 9));
__ addq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize));
#endif
__ pop(rbx);

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

@ -138,7 +138,7 @@ class UnaryOpStub: public PlatformCodeStub {
void GenerateGenericStubBitNot(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() {
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 {
public:
#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
static const int kCallerFPOffset = -8 * kPointerSize;
#endif

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

@ -3968,18 +3968,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
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:
EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
break;

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

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

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

@ -34,6 +34,7 @@
#include "deoptimizer.h"
#include "safepoint-table.h"
#include "scopes.h"
#include "v8utils.h"
#include "x64/lithium-gap-resolver-x64.h"
namespace v8 {
@ -172,7 +173,7 @@ class LCodeGen BASE_EMBEDDED {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
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()); }

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();
for (int i = 0; i < block->phis()->length(); ++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) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
if (block->deleted_phis()->at(i) < last_environment->length()) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
}
block->UpdateEnvironment(last_environment);
// Pick up the outgoing argument count of one of the predecessors.
@ -1610,7 +1614,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
HCompareObjectEqAndBranch* instr) {
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right());
LOperand* right = UseRegisterOrConstantAtStart(instr->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_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):
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()
for filename in files:
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)
tests.append(test)
return tests
@ -109,116 +109,3 @@ class MessageTestSuite(testsuite.TestSuite):
def GetSuite(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
// 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.
@ -55,6 +55,8 @@ function TestGeneratorObject() {
var iter = g();
assertSame(g.prototype, Object.getPrototypeOf(iter));
assertTrue(iter instanceof g);
assertEquals("Generator", %ClassOf(iter));
assertEquals("[object Generator]", String(iter));
assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== g());
@ -62,7 +64,30 @@ function TestGeneratorObject() {
iter = new g();
assertSame(g.prototype, Object.getPrototypeOf(iter));
assertTrue(iter instanceof g);
assertEquals("Generator", %ClassOf(iter));
assertEquals("[object Generator]", String(iter));
assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== new g());
}
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);
/* TODO[dslomov]: Reenable the test
assertThrows(function() {
var ab1 = new __ArrayBuffer(0xFFFFFFFFFFFF)
}, RangeError);
*/
var ab = new __ArrayBuffer();
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
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_BUILTINS_DECLS_H_
#define V8_BUILTINS_DECLS_H_
// Flags: --allow-natives-syntax
#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 {
namespace internal {
function test(crc32) {
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
#endif // V8_BUILTINS_DECLS_H_
test([0.5]);
test(a);
%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
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// 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.

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

@ -50,7 +50,7 @@ class MjsunitTestSuite(testsuite.TestSuite):
files.sort()
for filename in files:
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)
tests.append(test)
return tests
@ -95,134 +95,3 @@ class MjsunitTestSuite(testsuite.TestSuite):
def GetSuite(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
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:
return f.read()
@ -150,7 +150,7 @@ class MozillaTestSuite(testsuite.TestSuite):
if code != 0:
os.chdir(old_cwd)
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")
with tarfile.open(archive_file, "w:gz") as tar:
tar.add("data")
@ -161,96 +161,3 @@ class MozillaTestSuite(testsuite.TestSuite):
def GetSuite(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"
def _GetExpectations(self):
expects_file = join(self.root, "preparser.expectation")
expects_file = os.path.join(self.root, "preparser.expectation")
expectations_map = {}
if not os.path.exists(expects_file): return expectations_map
rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$")
@ -58,7 +58,7 @@ class PreparserTestSuite(testsuite.TestSuite):
return expectations_map
def _ParsePythonTestTemplates(self, result, filename):
pathname = join(self.root, filename + ".pyt")
pathname = os.path.join(self.root, filename + ".pyt")
def Test(name, source, expectation):
source = source.replace("\n", " ")
testname = os.path.join(filename, name)
@ -118,143 +118,3 @@ class PreparserTestSuite(testsuite.TestSuite):
def GetSuite(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