diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index a932e0bc30..03b96f1579 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,18 @@ +2009-08-05: Version 1.3.2 + + Started new compiler infrastructure for two-pass compilation using a + control flow graph constructed from the AST. + + Profiler stack sampling for X64. + + Safe handling of NaN to Posix platform-dependent time functions. + + Added a new profiler control API to unify controlling various aspects + of profiling. + + Fixed issue 392. + + 2009-07-30: Version 1.3.1 Speed improvements to accessors and interceptors. diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct index dbcd616862..8b48ad4590 100644 --- a/deps/v8/SConstruct +++ b/deps/v8/SConstruct @@ -126,6 +126,7 @@ LIBRARY_FLAGS = { 'os:linux': { 'CCFLAGS': ['-ansi'] + GCC_EXTRA_CCFLAGS, 'library:shared': { + 'CPPDEFINES': ['V8_SHARED'], 'LIBS': ['pthread'] } }, @@ -218,8 +219,11 @@ V8_EXTRA_FLAGS = { 'gcc': { 'all': { 'CXXFLAGS': [], #['-fvisibility=hidden'], - 'WARNINGFLAGS': ['-Wall', '-Werror', '-W', - '-Wno-unused-parameter'] + 'WARNINGFLAGS': ['-Wall', + '-Werror', + '-W', + '-Wno-unused-parameter', + '-Wnon-virtual-dtor'] }, 'os:win32': { 'WARNINGFLAGS': ['-pedantic', '-Wno-long-long'] diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h index 1a4840e8de..345d331a12 100644 --- a/deps/v8/include/v8-debug.h +++ b/deps/v8/include/v8-debug.h @@ -55,7 +55,7 @@ typedef long long int64_t; // NOLINT // Setup for Linux shared library export. See v8.h in this directory for // information on how to build/use V8 as shared library. -#if defined(__GNUC__) && (__GNUC__ >= 4) +#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED) #define EXPORT __attribute__ ((visibility("default"))) #else // defined(__GNUC__) && (__GNUC__ >= 4) #define EXPORT diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 5e3dbffb68..87e71031c7 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -85,11 +85,10 @@ typedef unsigned __int64 uint64_t; #include -// Setup for Linux shared library export. There is no need to destinguish -// neither between building or using the V8 shared library nor between using -// the shared or static V8 library as there is on Windows. Therefore there is -// no checking of BUILDING_V8_SHARED and USING_V8_SHARED. -#if defined(__GNUC__) && (__GNUC__ >= 4) +// Setup for Linux shared library export. There is no need to distinguish +// between building or using the V8 shared library, but we should not +// export symbols when we are building a static library. +#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED) #define V8EXPORT __attribute__ ((visibility("default"))) #define V8EXPORT_INLINE __attribute__ ((visibility("default"))) #else // defined(__GNUC__) && (__GNUC__ >= 4) @@ -1971,12 +1970,15 @@ typedef Persistent (*ContextGenerator)(); * * In V8, profiler consists of several modules: CPU profiler, and different * kinds of heap profiling. Each can be turned on / off independently. + * When PROFILER_MODULE_HEAP_SNAPSHOT flag is passed to ResumeProfilerEx, + * modules are enabled only temporarily for making a snapshot of the heap. */ enum ProfilerModules { PROFILER_MODULE_NONE = 0, PROFILER_MODULE_CPU = 1, PROFILER_MODULE_HEAP_STATS = 1 << 1, - PROFILER_MODULE_JS_CONSTRUCTORS = 1 << 2 + PROFILER_MODULE_JS_CONSTRUCTORS = 1 << 2, + PROFILER_MODULE_HEAP_SNAPSHOT = 1 << 16 }; diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript index f9f9634081..a9669a1229 100755 --- a/deps/v8/src/SConscript +++ b/deps/v8/src/SConscript @@ -36,25 +36,26 @@ Import('context') SOURCES = { 'all': [ 'accessors.cc', 'allocation.cc', 'api.cc', 'assembler.cc', 'ast.cc', - 'bootstrapper.cc', 'builtins.cc', 'checks.cc', 'code-stubs.cc', - 'codegen.cc', 'compilation-cache.cc', 'compiler.cc', 'contexts.cc', - 'conversions.cc', 'counters.cc', 'dateparser.cc', 'debug.cc', - 'debug-agent.cc', 'disassembler.cc', 'execution.cc', 'factory.cc', - 'flags.cc', 'frame-element.cc', 'frames.cc', 'func-name-inferrer.cc', - 'global-handles.cc', 'handles.cc', 'hashmap.cc', - 'heap.cc', 'ic.cc', 'interpreter-irregexp.cc', 'jsregexp.cc', - 'jump-target.cc', 'log.cc', 'log-utils.cc', 'mark-compact.cc', 'messages.cc', - 'objects.cc', 'oprofile-agent.cc', 'parser.cc', 'property.cc', - 'regexp-macro-assembler.cc', 'regexp-macro-assembler-irregexp.cc', - 'regexp-stack.cc', 'register-allocator.cc', 'rewriter.cc', 'runtime.cc', - 'scanner.cc', 'scopeinfo.cc', 'scopes.cc', 'serialize.cc', - 'snapshot-common.cc', 'spaces.cc', 'string-stream.cc', 'stub-cache.cc', - 'token.cc', 'top.cc', 'unicode.cc', 'usage-analyzer.cc', 'utils.cc', - 'v8-counters.cc', 'v8.cc', 'v8threads.cc', 'variables.cc', 'version.cc', + 'bootstrapper.cc', 'builtins.cc', 'checks.cc', 'cfg.cc', + 'code-stubs.cc', 'codegen.cc', 'compilation-cache.cc', 'compiler.cc', + 'contexts.cc', 'conversions.cc', 'counters.cc', 'dateparser.cc', + 'debug.cc', 'debug-agent.cc', 'disassembler.cc', 'execution.cc', + 'factory.cc', 'flags.cc', 'frame-element.cc', 'frames.cc', + 'func-name-inferrer.cc', 'global-handles.cc', 'handles.cc', + 'hashmap.cc', 'heap.cc', 'ic.cc', 'interpreter-irregexp.cc', + 'jsregexp.cc', 'jump-target.cc', 'log.cc', 'log-utils.cc', + 'mark-compact.cc', 'messages.cc', 'objects.cc', 'oprofile-agent.cc', + 'parser.cc', 'property.cc', 'regexp-macro-assembler.cc', + 'regexp-macro-assembler-irregexp.cc', 'regexp-stack.cc', + 'register-allocator.cc', 'rewriter.cc', 'runtime.cc', 'scanner.cc', + 'scopeinfo.cc', 'scopes.cc', 'serialize.cc', 'snapshot-common.cc', + 'spaces.cc', 'string-stream.cc', 'stub-cache.cc', 'token.cc', 'top.cc', + 'unicode.cc', 'usage-analyzer.cc', 'utils.cc', 'v8-counters.cc', + 'v8.cc', 'v8threads.cc', 'variables.cc', 'version.cc', 'virtual-frame.cc', 'zone.cc' ], 'arch:arm': [ - 'arm/assembler-arm.cc', 'arm/builtins-arm.cc', + 'arm/assembler-arm.cc', 'arm/builtins-arm.cc', 'arm/cfg-arm.cc', 'arm/codegen-arm.cc', 'arm/cpu-arm.cc', 'arm/disasm-arm.cc', 'arm/debug-arm.cc', 'arm/frames-arm.cc', 'arm/ic-arm.cc', 'arm/jump-target-arm.cc', 'arm/macro-assembler-arm.cc', @@ -63,7 +64,7 @@ SOURCES = { 'arm/virtual-frame-arm.cc' ], 'arch:ia32': [ - 'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc', + 'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc', 'ia32/cfg-ia32.cc', 'ia32/codegen-ia32.cc', 'ia32/cpu-ia32.cc', 'ia32/disasm-ia32.cc', 'ia32/debug-ia32.cc', 'ia32/frames-ia32.cc', 'ia32/ic-ia32.cc', 'ia32/jump-target-ia32.cc', 'ia32/macro-assembler-ia32.cc', @@ -72,7 +73,7 @@ SOURCES = { 'ia32/virtual-frame-ia32.cc' ], 'arch:x64': [ - 'x64/assembler-x64.cc', 'x64/builtins-x64.cc', + 'x64/assembler-x64.cc', 'x64/builtins-x64.cc', 'x64/cfg-x64.cc', 'x64/codegen-x64.cc', 'x64/cpu-x64.cc', 'x64/disasm-x64.cc', 'x64/debug-x64.cc', 'x64/frames-x64.cc', 'x64/ic-x64.cc', 'x64/jump-target-x64.cc', 'x64/macro-assembler-x64.cc', diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 08281012bd..9bc623a63a 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -3214,21 +3214,21 @@ void V8::SetGlobalGCEpilogueCallback(GCCallback callback) { void V8::PauseProfiler() { #ifdef ENABLE_LOGGING_AND_PROFILING - i::Logger::PauseProfiler(); + i::Logger::PauseProfiler(PROFILER_MODULE_CPU); #endif } void V8::ResumeProfiler() { #ifdef ENABLE_LOGGING_AND_PROFILING - i::Logger::ResumeProfiler(); + i::Logger::ResumeProfiler(PROFILER_MODULE_CPU); #endif } bool V8::IsProfilerPaused() { #ifdef ENABLE_LOGGING_AND_PROFILING - return i::Logger::IsProfilerPaused(); + return i::Logger::GetActiveProfilerModules() & PROFILER_MODULE_CPU; #else return true; #endif @@ -3237,11 +3237,19 @@ bool V8::IsProfilerPaused() { void V8::ResumeProfilerEx(int flags) { #ifdef ENABLE_LOGGING_AND_PROFILING - if (flags & PROFILER_MODULE_CPU) { - i::Logger::ResumeProfiler(); - } - if (flags & (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { - i::FLAG_log_gc = true; + if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) { + // Snapshot mode: resume modules, perform GC, then pause only + // those modules which haven't been started prior to making a + // snapshot. + + // Reset snapshot flag and CPU module flags. + flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU); + const int current_flags = i::Logger::GetActiveProfilerModules(); + i::Logger::ResumeProfiler(flags); + i::Heap::CollectAllGarbage(); + i::Logger::PauseProfiler(~current_flags & flags); + } else { + i::Logger::ResumeProfiler(flags); } #endif } @@ -3249,26 +3257,14 @@ void V8::ResumeProfilerEx(int flags) { void V8::PauseProfilerEx(int flags) { #ifdef ENABLE_LOGGING_AND_PROFILING - if (flags & PROFILER_MODULE_CPU) { - i::Logger::PauseProfiler(); - } - if (flags & (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { - i::FLAG_log_gc = false; - } + i::Logger::PauseProfiler(flags); #endif } int V8::GetActiveProfilerModules() { #ifdef ENABLE_LOGGING_AND_PROFILING - int result = PROFILER_MODULE_NONE; - if (!i::Logger::IsProfilerPaused()) { - result |= PROFILER_MODULE_CPU; - } - if (i::FLAG_log_gc) { - result |= PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS; - } - return result; + return i::Logger::GetActiveProfilerModules(); #else return PROFILER_MODULE_NONE; #endif diff --git a/deps/v8/src/arm/cfg-arm.cc b/deps/v8/src/arm/cfg-arm.cc new file mode 100644 index 0000000000..109067bea2 --- /dev/null +++ b/deps/v8/src/arm/cfg-arm.cc @@ -0,0 +1,124 @@ +// 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. + +#include "v8.h" + +#include "cfg.h" +#include "codegen-inl.h" +#include "macro-assembler-arm.h" + +namespace v8 { +namespace internal { + +#define __ ACCESS_MASM(masm) + +void InstructionBlock::Compile(MacroAssembler* masm) { + ASSERT(!is_marked()); + is_marked_ = true; + { + Comment cmt(masm, "[ InstructionBlock"); + for (int i = 0, len = instructions_.length(); i < len; i++) { + instructions_[i]->Compile(masm); + } + } + successor_->Compile(masm); +} + + +void EntryNode::Compile(MacroAssembler* masm) { + ASSERT(!is_marked()); + is_marked_ = true; + { + Comment cmnt(masm, "[ EntryNode"); + __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); + __ add(fp, sp, Operand(2 * kPointerSize)); + int count = CfgGlobals::current()->fun()->scope()->num_stack_slots(); + if (count > 0) { + __ mov(ip, Operand(Factory::undefined_value())); + for (int i = 0; i < count; i++) { + __ push(ip); + } + } + if (FLAG_trace) { + __ CallRuntime(Runtime::kTraceEnter, 0); + } + if (FLAG_check_stack) { + StackCheckStub stub; + __ CallStub(&stub); + } + } + successor_->Compile(masm); +} + + +void ExitNode::Compile(MacroAssembler* masm) { + ASSERT(!is_marked()); + is_marked_ = true; + Comment cmnt(masm, "[ ExitNode"); + if (FLAG_trace) { + __ push(r0); + __ CallRuntime(Runtime::kTraceExit, 1); + } + __ mov(sp, fp); + __ ldm(ia_w, sp, fp.bit() | lr.bit()); + int count = CfgGlobals::current()->fun()->scope()->num_parameters(); + __ add(sp, sp, Operand((count + 1) * kPointerSize)); + __ Jump(lr); +} + + +void ReturnInstr::Compile(MacroAssembler* masm) { + Comment cmnt(masm, "[ ReturnInstr"); + value_->ToRegister(masm, r0); +} + + +void Constant::ToRegister(MacroAssembler* masm, Register reg) { + __ mov(reg, Operand(handle_)); +} + + +void SlotLocation::ToRegister(MacroAssembler* masm, Register reg) { + switch (type_) { + case Slot::PARAMETER: { + int count = CfgGlobals::current()->fun()->scope()->num_parameters(); + __ ldr(reg, MemOperand(fp, (1 + count - index_) * kPointerSize)); + break; + } + case Slot::LOCAL: { + const int kOffset = JavaScriptFrameConstants::kLocal0Offset; + __ ldr(reg, MemOperand(fp, kOffset - index_ * kPointerSize)); + break; + } + default: + UNREACHABLE(); + } +} + +#undef __ + +} } // namespace v8::internal diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h index 406d43d056..3a309ac96a 100644 --- a/deps/v8/src/ast.h +++ b/deps/v8/src/ast.h @@ -821,9 +821,6 @@ class VariableProxy: public Expression { return (variable == NULL) ? false : variable->is_arguments(); } - // If this assertion fails it means that some code has tried to - // treat the special "this" variable as an ordinary variable with - // the name "this". Handle name() const { return name_; } Variable* var() const { return var_; } UseCount* var_uses() { return &var_uses_; } diff --git a/deps/v8/src/cfg.cc b/deps/v8/src/cfg.cc new file mode 100644 index 0000000000..bad1441170 --- /dev/null +++ b/deps/v8/src/cfg.cc @@ -0,0 +1,485 @@ +// 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. + +#include "v8.h" + +#include "bootstrapper.h" +#include "cfg.h" +#include "scopeinfo.h" +#include "scopes.h" + +namespace v8 { +namespace internal { + + +CfgGlobals* CfgGlobals::top_ = NULL; + + +CfgGlobals::CfgGlobals(FunctionLiteral* fun) + : global_fun_(fun), + global_exit_(new ExitNode()), +#ifdef DEBUG + node_counter_(0), +#endif + previous_(top_) { + top_ = this; +} + + +#define BAILOUT(reason) \ + do { return NULL; } while (false) + +Cfg* Cfg::Build() { + FunctionLiteral* fun = CfgGlobals::current()->fun(); + if (fun->scope()->num_heap_slots() > 0) { + BAILOUT("function has context slots"); + } + if (fun->scope()->arguments() != NULL) { + BAILOUT("function uses .arguments"); + } + + ZoneList* body = fun->body(); + if (body->is_empty()) { + BAILOUT("empty function body"); + } + + StatementBuilder builder; + builder.VisitStatements(body); + Cfg* cfg = builder.cfg(); + if (cfg == NULL) { + BAILOUT("unsupported statement type"); + } + if (cfg->has_exit()) { + BAILOUT("control path without explicit return"); + } + cfg->PrependEntryNode(); + return cfg; +} + +#undef BAILOUT + + +void Cfg::PrependEntryNode() { + ASSERT(!is_empty()); + entry_ = new EntryNode(InstructionBlock::cast(entry())); +} + + +void Cfg::Append(Instruction* instr) { + ASSERT(has_exit()); + ASSERT(!is_empty()); + InstructionBlock::cast(exit_)->Append(instr); +} + + +void Cfg::AppendReturnInstruction(Value* value) { + Append(new ReturnInstr(value)); + ExitNode* global_exit = CfgGlobals::current()->exit(); + InstructionBlock::cast(exit_)->set_successor(global_exit); + exit_ = NULL; +} + + +void InstructionBlock::Unmark() { + if (is_marked_) { + is_marked_ = false; + successor_->Unmark(); + } +} + + +void EntryNode::Unmark() { + if (is_marked_) { + is_marked_ = false; + successor_->Unmark(); + } +} + + +void ExitNode::Unmark() { + is_marked_ = false; +} + + +Handle Cfg::Compile(Handle