From 7fca10133861348417f33dac2d656cbfd9d1bb0d Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Tue, 5 Oct 2010 15:25:07 -0700 Subject: [PATCH] Upgrade V8 to 2.4.8 --- deps/v8/ChangeLog | 8 + deps/v8/src/api.cc | 8 +- deps/v8/src/arm/ic-arm.cc | 3 +- deps/v8/src/compiler.cc | 12 +- deps/v8/src/compiler.h | 3 +- deps/v8/src/handles.cc | 2 +- deps/v8/src/ia32/codegen-ia32.cc | 47 ++- deps/v8/src/ia32/ic-ia32.cc | 28 +- deps/v8/src/ic.cc | 10 +- deps/v8/src/ic.h | 3 +- deps/v8/src/jsregexp.cc | 4 +- deps/v8/src/liveedit.cc | 13 +- deps/v8/src/log-utils.h | 1 + deps/v8/src/objects-visiting.h | 6 +- deps/v8/src/objects.cc | 5 + deps/v8/src/objects.h | 2 +- deps/v8/src/parser.cc | 284 +--------------- deps/v8/src/parser.h | 307 ++++++++++++++++-- deps/v8/src/profile-generator.cc | 49 ++- deps/v8/src/profile-generator.h | 4 +- deps/v8/src/v8-counters.h | 2 + deps/v8/src/version.cc | 4 +- deps/v8/src/x64/builtins-x64.cc | 2 +- deps/v8/src/x64/code-stubs-x64.cc | 2 +- deps/v8/src/x64/codegen-x64.cc | 14 +- deps/v8/src/x64/full-codegen-x64.cc | 8 +- deps/v8/src/x64/ic-x64.cc | 5 +- deps/v8/src/x64/macro-assembler-x64.cc | 10 +- deps/v8/src/x64/macro-assembler-x64.h | 34 +- deps/v8/test/cctest/cctest.status | 5 - deps/v8/test/cctest/test-api.cc | 154 ++++++++- deps/v8/test/cctest/test-heap-profiler.cc | 18 +- .../test/cctest/test-macro-assembler-x64.cc | 14 +- deps/v8/test/cctest/test-regexp.cc | 12 +- 34 files changed, 652 insertions(+), 431 deletions(-) diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 134540d3f0..42de286502 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,11 @@ +2010-10-04: Version 2.4.8 + + Fixed a bug in ResumeProfilerEx causing it to not always write out the + whole snapshot (issue 868). + + Performance improvements on all platforms. + + 2010-09-30: Version 2.4.7 Changed the command-line flag --max-new-space-size to be in kB and the diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index b7d85c68a1..350410a3cc 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -1,4 +1,4 @@ -// Copyright 2009 the V8 project authors. All rights reserved. +// Copyright 2010 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: @@ -28,6 +28,7 @@ #include "v8.h" #include "api.h" + #include "arguments.h" #include "bootstrapper.h" #include "compiler.h" @@ -36,6 +37,7 @@ #include "global-handles.h" #include "heap-profiler.h" #include "messages.h" +#include "parser.h" #include "platform.h" #include "profile-generator-inl.h" #include "serialize.h" @@ -1135,13 +1137,13 @@ void ObjectTemplate::SetInternalFieldCount(int value) { ScriptData* ScriptData::PreCompile(const char* input, int length) { unibrow::Utf8InputBuffer<> buf(input, length); - return i::PreParse(i::Handle(), &buf, NULL); + return i::Parser::PreParse(i::Handle(), &buf, NULL); } ScriptData* ScriptData::PreCompile(v8::Handle source) { i::Handle str = Utils::OpenHandle(*source); - return i::PreParse(str, NULL, NULL); + return i::Parser::PreParse(str, NULL, NULL); } diff --git a/deps/v8/src/arm/ic-arm.cc b/deps/v8/src/arm/ic-arm.cc index eab4c6e8ed..7f83d14af9 100644 --- a/deps/v8/src/arm/ic-arm.cc +++ b/deps/v8/src/arm/ic-arm.cc @@ -969,7 +969,8 @@ bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { bool LoadIC::PatchInlinedContextualLoad(Address address, Object* map, - Object* cell) { + Object* cell, + bool is_dont_delete) { // TODO(): implement this. return false; } diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 6ef5a1c50d..bfb2e21bea 100755 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -27,18 +27,20 @@ #include "v8.h" +#include "compiler.h" + #include "bootstrapper.h" #include "codegen-inl.h" #include "compilation-cache.h" -#include "compiler.h" #include "data-flow.h" #include "debug.h" #include "full-codegen.h" #include "liveedit.h" #include "oprofile-agent.h" +#include "parser.h" #include "rewriter.h" -#include "scopes.h" #include "scopeinfo.h" +#include "scopes.h" namespace v8 { namespace internal { @@ -174,7 +176,7 @@ static Handle MakeFunctionInfo(bool is_global, // Build AST. EagerCompilationInfo info(script, is_eval); FunctionLiteral* lit = - MakeAST(is_global, script, extension, pre_data, is_json); + Parser::MakeAST(is_global, script, extension, pre_data, is_json); // Check for parse errors. if (lit == NULL) { @@ -283,7 +285,7 @@ Handle Compiler::Compile(Handle source, if (pre_data == NULL && FLAG_lazy && source_length >= FLAG_min_preparse_length) { - pre_data = PartialPreParse(source, NULL, extension); + pre_data = Parser::PartialPreParse(source, NULL, extension); } // Create a script object describing the script to be compiled. @@ -382,7 +384,7 @@ bool Compiler::CompileLazy(CompilationInfo* info) { // Generate the AST for the lazily compiled function. The AST may be // NULL in case of parser stack overflow. - FunctionLiteral* lit = MakeLazyAST(shared); + FunctionLiteral* lit = Parser::MakeLazyAST(shared); // Check for parse errors. if (lit == NULL) { diff --git a/deps/v8/src/compiler.h b/deps/v8/src/compiler.h index ae0d6def6d..d8eb3a68f4 100644 --- a/deps/v8/src/compiler.h +++ b/deps/v8/src/compiler.h @@ -30,13 +30,14 @@ #include "ast.h" #include "frame-element.h" -#include "parser.h" #include "register-allocator.h" #include "zone.h" namespace v8 { namespace internal { +class ScriptDataImpl; + // CompilationInfo encapsulates some information known at compile time. It // is constructed based on the resources available at compile-time. class CompilationInfo BASE_EMBEDDED { diff --git a/deps/v8/src/handles.cc b/deps/v8/src/handles.cc index 02074925e5..3fed0bcc0c 100644 --- a/deps/v8/src/handles.cc +++ b/deps/v8/src/handles.cc @@ -175,7 +175,7 @@ static int ExpectedNofPropertiesFromEstimate(int estimate) { // Inobject slack tracking will reclaim redundant inobject space later, // so we can afford to adjust the estimate generously. - return estimate + 6; + return estimate + 8; } diff --git a/deps/v8/src/ia32/codegen-ia32.cc b/deps/v8/src/ia32/codegen-ia32.cc index 9c8573cea0..c006b86951 100644 --- a/deps/v8/src/ia32/codegen-ia32.cc +++ b/deps/v8/src/ia32/codegen-ia32.cc @@ -9149,7 +9149,8 @@ class DeferredReferenceGetNamedValue: public DeferredCode { : dst_(dst), receiver_(receiver), name_(name), - is_contextual_(is_contextual) { + is_contextual_(is_contextual), + is_dont_delete_(false) { set_comment(is_contextual ? "[ DeferredReferenceGetNamedValue (contextual)" : "[ DeferredReferenceGetNamedValue"); @@ -9159,12 +9160,18 @@ class DeferredReferenceGetNamedValue: public DeferredCode { Label* patch_site() { return &patch_site_; } + void set_is_dont_delete(bool value) { + ASSERT(is_contextual_); + is_dont_delete_ = value; + } + private: Label patch_site_; Register dst_; Register receiver_; Handle name_; bool is_contextual_; + bool is_dont_delete_; }; @@ -9181,8 +9188,8 @@ void DeferredReferenceGetNamedValue::Generate() { // The call must be followed by: // - a test eax instruction to indicate that the inobject property // case was inlined. - // - a mov ecx instruction to indicate that the contextual property - // load was inlined. + // - a mov ecx or mov edx instruction to indicate that the + // contextual property load was inlined. // // Store the delta to the map check instruction here in the test // instruction. Use masm_-> instead of the __ macro since the @@ -9191,8 +9198,11 @@ void DeferredReferenceGetNamedValue::Generate() { // Here we use masm_-> instead of the __ macro because this is the // instruction that gets patched and coverage code gets in the way. if (is_contextual_) { - masm_->mov(ecx, -delta_to_patch_site); + masm_->mov(is_dont_delete_ ? edx : ecx, -delta_to_patch_site); __ IncrementCounter(&Counters::named_load_global_inline_miss, 1); + if (is_dont_delete_) { + __ IncrementCounter(&Counters::dont_delete_hint_miss, 1); + } } else { masm_->test(eax, Immediate(-delta_to_patch_site)); __ IncrementCounter(&Counters::named_load_inline_miss, 1); @@ -9436,9 +9446,34 @@ Result CodeGenerator::EmitNamedLoad(Handle name, bool is_contextual) { } __ mov(result.reg(), FieldOperand(result.reg(), JSGlobalPropertyCell::kValueOffset)); - __ cmp(result.reg(), Factory::the_hole_value()); - deferred->Branch(equal); + bool is_dont_delete = false; + if (!info_->closure().is_null()) { + // When doing lazy compilation we can check if the global cell + // already exists and use its "don't delete" status as a hint. + AssertNoAllocation no_gc; + v8::internal::GlobalObject* global_object = + info_->closure()->context()->global(); + LookupResult lookup; + global_object->LocalLookupRealNamedProperty(*name, &lookup); + if (lookup.IsProperty() && lookup.type() == NORMAL) { + ASSERT(lookup.holder() == global_object); + ASSERT(global_object->property_dictionary()->ValueAt( + lookup.GetDictionaryEntry())->IsJSGlobalPropertyCell()); + is_dont_delete = lookup.IsDontDelete(); + } + } + deferred->set_is_dont_delete(is_dont_delete); + if (!is_dont_delete) { + __ cmp(result.reg(), Factory::the_hole_value()); + deferred->Branch(equal); + } else if (FLAG_debug_code) { + __ cmp(result.reg(), Factory::the_hole_value()); + __ Check(not_equal, "DontDelete cells can't contain the hole"); + } __ IncrementCounter(&Counters::named_load_global_inline, 1); + if (is_dont_delete) { + __ IncrementCounter(&Counters::dont_delete_hint_hit, 1); + } } else { // The initial (invalid) offset has to be large enough to force a 32-bit // instruction encoding to allow patching with an arbitrary offset. Use diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc index a2990a20e3..b5f4deefeb 100644 --- a/deps/v8/src/ia32/ic-ia32.cc +++ b/deps/v8/src/ia32/ic-ia32.cc @@ -1662,17 +1662,37 @@ bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { // One byte opcode for mov ecx,0xXXXXXXXX. +// Marks inlined contextual loads using all kinds of cells. Generated +// code has the hole check: +// mov reg, +// mov reg, (, value offset) +// cmp reg, +// je slow +// ;; use reg static const byte kMovEcxByte = 0xB9; +// One byte opcode for mov edx,0xXXXXXXXX. +// Marks inlined contextual loads using only "don't delete" +// cells. Generated code doesn't have the hole check: +// mov reg, +// mov reg, (, value offset) +// ;; use reg +static const byte kMovEdxByte = 0xBA; + bool LoadIC::PatchInlinedContextualLoad(Address address, Object* map, - Object* cell) { + Object* cell, + bool is_dont_delete) { // The address of the instruction following the call. Address mov_instruction_address = address + Assembler::kCallTargetAddressOffset; - // If the instruction following the call is not a cmp eax, nothing - // was inlined. - if (*mov_instruction_address != kMovEcxByte) return false; + // If the instruction following the call is not a mov ecx/edx, + // nothing was inlined. + byte b = *mov_instruction_address; + if (b != kMovEcxByte && b != kMovEdxByte) return false; + // If we don't have the hole check generated, we can only support + // "don't delete" cells. + if (b == kMovEdxByte && !is_dont_delete) return false; Address delta_address = mov_instruction_address + 1; // The delta to the start of the map check instruction. diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc index a9c2a4837c..adf365af0f 100644 --- a/deps/v8/src/ic.cc +++ b/deps/v8/src/ic.cc @@ -299,7 +299,10 @@ void LoadIC::ClearInlinedVersion(Address address) { // present) to guarantee failure by holding an invalid map (the null // value). The offset can be patched to anything. PatchInlinedLoad(address, Heap::null_value(), 0); - PatchInlinedContextualLoad(address, Heap::null_value(), Heap::null_value()); + PatchInlinedContextualLoad(address, + Heap::null_value(), + Heap::null_value(), + true); } @@ -848,7 +851,10 @@ Object* LoadIC::Load(State state, Handle object, Handle name) { JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast( lookup.holder()->property_dictionary()->ValueAt( lookup.GetDictionaryEntry())); - if (PatchInlinedContextualLoad(address(), map, cell)) { + if (PatchInlinedContextualLoad(address(), + map, + cell, + lookup.IsDontDelete())) { set_target(megamorphic_stub()); TRACE_IC_NAMED("[LoadIC : inline contextual patch %s]\n", name); ASSERT(cell->value() != Heap::the_hole_value()); diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h index a5fada09f4..437e45a935 100644 --- a/deps/v8/src/ic.h +++ b/deps/v8/src/ic.h @@ -300,7 +300,8 @@ class LoadIC: public IC { static bool PatchInlinedContextualLoad(Address address, Object* map, - Object* cell); + Object* cell, + bool is_dont_delete); friend class IC; }; diff --git a/deps/v8/src/jsregexp.cc b/deps/v8/src/jsregexp.cc index 30d4dcbf23..82a370f141 100644 --- a/deps/v8/src/jsregexp.cc +++ b/deps/v8/src/jsregexp.cc @@ -125,7 +125,7 @@ Handle RegExpImpl::Compile(Handle re, PostponeInterruptsScope postpone; RegExpCompileData parse_result; FlatStringReader reader(pattern); - if (!ParseRegExp(&reader, flags.is_multiline(), &parse_result)) { + if (!Parser::ParseRegExp(&reader, flags.is_multiline(), &parse_result)) { // Throw an exception if we fail to parse the pattern. ThrowRegExpException(re, pattern, @@ -267,7 +267,7 @@ bool RegExpImpl::CompileIrregexp(Handle re, bool is_ascii) { RegExpCompileData compile_data; FlatStringReader reader(pattern); - if (!ParseRegExp(&reader, flags.is_multiline(), &compile_data)) { + if (!Parser::ParseRegExp(&reader, flags.is_multiline(), &compile_data)) { // Throw an exception if we fail to parse the pattern. // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once. ThrowRegExpException(re, diff --git a/deps/v8/src/liveedit.cc b/deps/v8/src/liveedit.cc index 2fae3afb1c..cfd2e357cc 100644 --- a/deps/v8/src/liveedit.cc +++ b/deps/v8/src/liveedit.cc @@ -29,13 +29,15 @@ #include "v8.h" #include "liveedit.h" + #include "compiler.h" -#include "oprofile-agent.h" -#include "scopes.h" -#include "scopeinfo.h" -#include "global-handles.h" #include "debug.h" +#include "global-handles.h" #include "memory.h" +#include "oprofile-agent.h" +#include "parser.h" +#include "scopeinfo.h" +#include "scopes.h" namespace v8 { namespace internal { @@ -409,7 +411,8 @@ static void CompileScriptForTracker(Handle