diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index b299d99b09..8922db6400 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,17 @@ +2012-02-27: Version 3.9.11 + + Make 'module' a context-sensitive keyword (V8 issue 1957). + + +2012-02-24: Version 3.9.10 + + Fixed V8 issues 1322, 1772 and 1969. + + Conformance improvements. + + Performance and stability improvements on all platforms. + + 2012-02-23: Version 3.9.9 Supported fast case for-in in Crankshaft. diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index 5d47dec6f8..9976d25047 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -83,6 +83,7 @@ 'v8_use_snapshot%': 'true', 'host_os%': '<(OS)', 'v8_use_liveobjectlist%': 'false', + 'werror%': '-Werror', # With post mortem support enabled, metadata is embedded into libv8 that # describes various parameters of the VM for use by debuggers. See @@ -304,7 +305,7 @@ 'cflags': [ '-I/usr/pkg/include' ], }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', { - 'cflags': [ '<(werror)', '-W', '-Wno-unused-parameter', + 'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter', '-Wnon-virtual-dtor', '-Woverloaded-virtual' ], }], ], @@ -351,6 +352,7 @@ }], # OS=="mac" ['OS=="win"', { 'msvs_configuration_attributes': { + 'OutputDirectory': '<(DEPTH)\\build\\$(ConfigurationName)', 'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)', 'CharacterSet': '1', }, diff --git a/deps/v8/build/standalone.gypi b/deps/v8/build/standalone.gypi index add9d3ba53..e9b056580d 100644 --- a/deps/v8/build/standalone.gypi +++ b/deps/v8/build/standalone.gypi @@ -61,6 +61,7 @@ 'host_arch%': '<(host_arch)', 'target_arch%': '<(target_arch)', 'v8_target_arch%': '<(v8_target_arch)', + 'werror%': '-Werror', 'conditions': [ ['(v8_target_arch=="arm" and host_arch!="arm") or \ (v8_target_arch=="mips" and host_arch!="mips") or \ @@ -83,7 +84,7 @@ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \ or OS=="netbsd"', { 'target_defaults': { - 'cflags': [ '-W', '-Wno-unused-parameter', + 'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter', '-Wnon-virtual-dtor', '-pthread', '-fno-rtti', '-fno-exceptions', '-pedantic' ], 'ldflags': [ '-pthread', ], diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 524fcb2b46..a29cd9f718 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -3850,7 +3850,7 @@ class Internals { static const int kFullStringRepresentationMask = 0x07; static const int kExternalTwoByteRepresentationTag = 0x02; - static const int kJSObjectType = 0xa8; + static const int kJSObjectType = 0xa9; static const int kFirstNonstringType = 0x80; static const int kForeignType = 0x85; diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript index 42de36bc86..94840dc8b5 100755 --- a/deps/v8/src/SConscript +++ b/deps/v8/src/SConscript @@ -1,4 +1,4 @@ -# Copyright 2011 the V8 project authors. All rights reserved. +# 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: @@ -78,7 +78,6 @@ SOURCES = { fast-dtoa.cc fixed-dtoa.cc handles.cc - hashmap.cc heap-profiler.cc heap.cc hydrogen.cc @@ -246,7 +245,6 @@ PREPARSER_SOURCES = { dtoa.cc fast-dtoa.cc fixed-dtoa.cc - hashmap.cc preparse-data.cc preparser.cc preparser-api.cc diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 67fded8eb0..775c884c59 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -2760,6 +2760,7 @@ bool v8::Object::Set(uint32_t index, v8::Handle value) { self, index, value_obj, + NONE, i::kNonStrictMode); has_pending_exception = obj.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, false); diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index b48e842be7..51e9208332 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -109,6 +109,11 @@ class JumpPatchSite BASE_EMBEDDED { }; +int FullCodeGenerator::self_optimization_header_size() { + return 24; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right. The actual // argument count matches the formal parameter count expected by the @@ -130,13 +135,6 @@ void FullCodeGenerator::Generate() { SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); -#ifdef DEBUG - if (strlen(FLAG_stop_at) > 0 && - info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { - __ stop("stop-at"); - } -#endif - // We can optionally optimize based on counters rather than statistical // sampling. if (info->ShouldSelfOptimize()) { @@ -144,6 +142,7 @@ void FullCodeGenerator::Generate() { PrintF("[adding self-optimization header to %s]\n", *info->function()->debug_name()->ToCString()); } + has_self_optimization_header_ = true; MaybeObject* maybe_cell = isolate()->heap()->AllocateJSGlobalPropertyCell( Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt)); JSGlobalPropertyCell* cell; @@ -155,9 +154,17 @@ void FullCodeGenerator::Generate() { Handle compile_stub( isolate()->builtins()->builtin(Builtins::kLazyRecompile)); __ Jump(compile_stub, RelocInfo::CODE_TARGET, eq); + ASSERT(masm_->pc_offset() == self_optimization_header_size()); } } +#ifdef DEBUG + if (strlen(FLAG_stop_at) > 0 && + info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { + __ stop("stop-at"); + } +#endif + // Strict mode functions and builtins need to replace the receiver // with undefined when called as functions (without an explicit // receiver object). r5 is zero for method calls and non-zero for diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc index c98aaa916b..ca3ab7851d 100644 --- a/deps/v8/src/ast.cc +++ b/deps/v8/src/ast.cc @@ -237,8 +237,8 @@ bool IsEqualNumber(void* first, void* second) { void ObjectLiteral::CalculateEmitStore() { - HashMap properties(&IsEqualString); - HashMap elements(&IsEqualNumber); + ZoneHashMap properties(&IsEqualString); + ZoneHashMap elements(&IsEqualNumber); for (int i = this->properties()->length() - 1; i >= 0; i--) { ObjectLiteral::Property* property = this->properties()->at(i); Literal* literal = property->key(); @@ -249,7 +249,7 @@ void ObjectLiteral::CalculateEmitStore() { } uint32_t hash; - HashMap* table; + ZoneHashMap* table; void* key; Factory* factory = Isolate::Current()->factory(); if (handle->IsSymbol()) { diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 0f5b9c84a9..19a6a15990 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -214,13 +214,12 @@ class Genesis BASE_EMBEDDED { }; class ExtensionStates { - public: + public: ExtensionStates(); ExtensionTraversalState get_state(RegisteredExtension* extension); void set_state(RegisteredExtension* extension, ExtensionTraversalState state); - private: - Allocator allocator_; + private: HashMap map_; DISALLOW_COPY_AND_ASSIGN(ExtensionStates); }; @@ -1961,9 +1960,7 @@ static bool MatchRegisteredExtensions(void* key1, void* key2) { } Genesis::ExtensionStates::ExtensionStates() - : allocator_(), - map_(MatchRegisteredExtensions, &allocator_, 8) - {} + : map_(MatchRegisteredExtensions, 8) { } Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state( RegisteredExtension* extension) { diff --git a/deps/v8/src/compilation-cache.h b/deps/v8/src/compilation-cache.h index 31f2909680..2f2fbadb2e 100644 --- a/deps/v8/src/compilation-cache.h +++ b/deps/v8/src/compilation-cache.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// 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: @@ -31,8 +31,6 @@ namespace v8 { namespace internal { -class HashMap; - // The compilation cache consists of several generational sub-caches which uses // this class as a base class. A sub-cache contains a compilation cache tables // for each generation of the sub-cache. Since the same source code string has diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 5d7dbd1624..cbf53a5e86 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -118,6 +118,7 @@ bool CompilationInfo::ShouldSelfOptimize() { FLAG_crankshaft && !Serializer::enabled() && !function()->flags()->Contains(kDontSelfOptimize) && + !function()->flags()->Contains(kDontOptimize) && (shared_info().is_null() || !shared_info()->optimization_disabled()); } diff --git a/deps/v8/src/cpu-profiler.h b/deps/v8/src/cpu-profiler.h index 3f4fec5f45..6e2e771a41 100644 --- a/deps/v8/src/cpu-profiler.h +++ b/deps/v8/src/cpu-profiler.h @@ -1,4 +1,4 @@ -// Copyright 2010 the V8 project authors. All rights reserved. +// 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: @@ -41,7 +41,6 @@ class CodeEntry; class CodeMap; class CpuProfile; class CpuProfilesCollection; -class HashMap; class ProfileGenerator; class TokenEnumerator; diff --git a/deps/v8/src/d8.js b/deps/v8/src/d8.js index d136393e78..bf269230b8 100644 --- a/deps/v8/src/d8.js +++ b/deps/v8/src/d8.js @@ -122,13 +122,15 @@ Debug.State = { }; var trace_compile = false; // Tracing all compile events? var trace_debug_json = false; // Tracing all debug json packets? -var last_cmd_line = ''; +var last_cmd = ''; //var lol_is_enabled; // Set to true in d8.cc if LIVE_OBJECT_LIST is defined. var lol_next_dump_index = 0; var kDefaultLolLinesToPrintAtATime = 10; var kMaxLolLinesToPrintAtATime = 1000; var repeat_cmd_line = ''; var is_running = true; +// Global variable used to store whether a handle was requested. +var lookup_handle = null; // Copied from debug-delay.js. This is needed below: function ScriptTypeFlag(type) { @@ -155,7 +157,7 @@ function DebugMessageDetails(message) { } function DebugEventDetails(response) { - details = {text:'', running:false}; + var details = {text:'', running:false}; // Get the running state. details.running = response.running(); @@ -588,7 +590,6 @@ DebugRequest.prototype.createLOLRequest = function(command, // Create a JSON request for the evaluation command. DebugRequest.prototype.makeEvaluateJSONRequest_ = function(expression) { - // Global varaible used to store whether a handle was requested. lookup_handle = null; if (lol_is_enabled) { @@ -1948,7 +1949,7 @@ function roundNumber(num, length) { // Convert a JSON response to text for display in a text based debugger. function DebugResponseDetails(response) { - details = { text: '', running: false }; + var details = { text: '', running: false }; try { if (!response.success()) { diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc index f2c4dda875..2058d48b71 100644 --- a/deps/v8/src/debug.cc +++ b/deps/v8/src/debug.cc @@ -37,6 +37,7 @@ #include "debug.h" #include "deoptimizer.h" #include "execution.h" +#include "full-codegen.h" #include "global-handles.h" #include "ic.h" #include "ic-inl.h" @@ -1752,7 +1753,6 @@ static bool CompileFullCodeForDebugging(Handle shared, ASSERT(new_code->has_debug_break_slots()); ASSERT(current_code->is_compiled_optimizable() == new_code->is_compiled_optimizable()); - ASSERT(current_code->instruction_size() <= new_code->instruction_size()); } #endif return result; @@ -1830,6 +1830,13 @@ static void RedirectActivationsToRecompiledCodeOnThread( // break slots. debug_break_slot_count++; } + if (frame_code->has_self_optimization_header() && + !new_code->has_self_optimization_header()) { + delta -= FullCodeGenerator::self_optimization_header_size(); + } else { + ASSERT(frame_code->has_self_optimization_header() == + new_code->has_self_optimization_header()); + } int debug_break_slot_bytes = debug_break_slot_count * Assembler::kDebugBreakSlotLength; if (FLAG_trace_deopt) { diff --git a/deps/v8/src/deoptimizer.cc b/deps/v8/src/deoptimizer.cc index 682eb535ce..55ecc71dab 100644 --- a/deps/v8/src/deoptimizer.cc +++ b/deps/v8/src/deoptimizer.cc @@ -451,7 +451,7 @@ Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { base = data->lazy_deoptimization_entry_code_; } return - static_cast
(base->body()) + (id * table_entry_size_); + static_cast
(base->area_start()) + (id * table_entry_size_); } @@ -464,14 +464,14 @@ int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { base = data->lazy_deoptimization_entry_code_; } if (base == NULL || - addr < base->body() || - addr >= base->body() + + addr < base->area_start() || + addr >= base->area_start() + (kNumberOfEntries * table_entry_size_)) { return kNotDeoptimizationEntry; } ASSERT_EQ(0, - static_cast(addr - base->body()) % table_entry_size_); - return static_cast(addr - base->body()) / table_entry_size_; + static_cast(addr - base->area_start()) % table_entry_size_); + return static_cast(addr - base->area_start()) / table_entry_size_; } @@ -1152,11 +1152,12 @@ MemoryChunk* Deoptimizer::CreateCode(BailoutType type) { Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size, EXECUTABLE, NULL); + ASSERT(chunk->area_size() >= desc.instr_size); if (chunk == NULL) { V8::FatalProcessOutOfMemory("Not enough memory for deoptimization table"); } - memcpy(chunk->body(), desc.buffer, desc.instr_size); - CPU::FlushICache(chunk->body(), desc.instr_size); + memcpy(chunk->area_start(), desc.buffer, desc.instr_size); + CPU::FlushICache(chunk->area_start(), desc.instr_size); return chunk; } diff --git a/deps/v8/src/elements.cc b/deps/v8/src/elements.cc index c15c44d2ea..d951b0ee5f 100644 --- a/deps/v8/src/elements.cc +++ b/deps/v8/src/elements.cc @@ -705,10 +705,20 @@ class NonStrictArgumentsElementsAccessor } else { // Object is not mapped, defer to the arguments. FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); - return ElementsAccessor::ForArray(arguments)->Get(arguments, - key, - obj, - receiver); + MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( + arguments, key, obj, receiver); + Object* result; + if (!maybe_result->ToObject(&result)) return maybe_result; + // Elements of the arguments object in slow mode might be slow aliases. + if (result->IsAliasedArgumentsEntry()) { + AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(result); + Context* context = Context::cast(parameter_map->get(0)); + int context_index = entry->aliased_context_slot(); + ASSERT(!context->get(context_index)->IsTheHole()); + return context->get(context_index); + } else { + return result; + } } } diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h index bec85bfa2a..2968445d87 100644 --- a/deps/v8/src/flag-definitions.h +++ b/deps/v8/src/flag-definitions.h @@ -169,6 +169,9 @@ DEFINE_int(stress_runs, 0, "number of stress runs") DEFINE_bool(optimize_closures, true, "optimize closures") DEFINE_int(loop_weight, 1, "loop weight for representation inference") +DEFINE_bool(optimize_for_in, false, + "optimize functions containing for-in loops") + // Experimental profiler changes. DEFINE_bool(experimental_profiler, false, "enable all profiler experiments") DEFINE_bool(watch_ic_patching, false, "profiler considers IC stability") diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc index 3d10e96b53..9639542740 100644 --- a/deps/v8/src/full-codegen.cc +++ b/deps/v8/src/full-codegen.cc @@ -302,6 +302,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); Handle code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); code->set_optimizable(info->IsOptimizable()); + code->set_self_optimization_header(cgen.has_self_optimization_header_); cgen.PopulateDeoptimizationData(code); cgen.PopulateTypeFeedbackInfo(code); cgen.PopulateTypeFeedbackCells(code); @@ -365,6 +366,7 @@ void FullCodeGenerator::PopulateDeoptimizationData(Handle code) { void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle code) { Handle info = isolate()->factory()->NewTypeFeedbackInfo(); info->set_ic_total_count(ic_total_count_); + ASSERT(!isolate()->heap()->InNewSpace(*info)); code->set_type_feedback_info(*info); } diff --git a/deps/v8/src/full-codegen.h b/deps/v8/src/full-codegen.h index c1dec15e81..0ffb885272 100644 --- a/deps/v8/src/full-codegen.h +++ b/deps/v8/src/full-codegen.h @@ -90,10 +90,15 @@ class FullCodeGenerator: public AstVisitor { stack_checks_(2), // There's always at least one. type_feedback_cells_(info->HasDeoptimizationSupport() ? info->function()->ast_node_count() : 0), - ic_total_count_(0) { } + ic_total_count_(0), + has_self_optimization_header_(false) { } static bool MakeCode(CompilationInfo* info); + // Returns the platform-specific size in bytes of the self-optimization + // header. + static int self_optimization_header_size(); + // Encode state and pc-offset as a BitField. // Only use 30 bits because we encode the result as a smi. class StateField : public BitField { }; @@ -786,6 +791,7 @@ class FullCodeGenerator: public AstVisitor { ZoneList stack_checks_; ZoneList type_feedback_cells_; int ic_total_count_; + bool has_self_optimization_header_; Handle handler_table_; Handle profiling_counter_; diff --git a/deps/v8/src/hashmap.cc b/deps/v8/src/hashmap.cc deleted file mode 100644 index 0b404a97e1..0000000000 --- a/deps/v8/src/hashmap.cc +++ /dev/null @@ -1,224 +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. - -#include "../include/v8stdint.h" -#include "globals.h" -#include "checks.h" -#include "utils.h" -#include "allocation.h" - -#include "hashmap.h" - -namespace v8 { -namespace internal { - -Allocator* HashMap::DefaultAllocator = ::new Allocator(); - - -HashMap::HashMap(MatchFun match, - Allocator* allocator, - uint32_t initial_capacity) { - allocator_ = allocator; - match_ = match; - Initialize(initial_capacity); -} - - -HashMap::~HashMap() { - if (allocator_) { - allocator_->Delete(map_); - } -} - - -HashMap::Entry* HashMap::Lookup(void* key, uint32_t hash, bool insert) { - // Find a matching entry. - Entry* p = Probe(key, hash); - if (p->key != NULL) { - return p; - } - - // No entry found; insert one if necessary. - if (insert) { - p->key = key; - p->value = NULL; - p->hash = hash; - occupancy_++; - - // Grow the map if we reached >= 80% occupancy. - if (occupancy_ + occupancy_/4 >= capacity_) { - Resize(); - p = Probe(key, hash); - } - - return p; - } - - // No entry found and none inserted. - return NULL; -} - - -void HashMap::Remove(void* key, uint32_t hash) { - // Lookup the entry for the key to remove. - Entry* p = Probe(key, hash); - if (p->key == NULL) { - // Key not found nothing to remove. - return; - } - - // To remove an entry we need to ensure that it does not create an empty - // entry that will cause the search for another entry to stop too soon. If all - // the entries between the entry to remove and the next empty slot have their - // initial position inside this interval, clearing the entry to remove will - // not break the search. If, while searching for the next empty entry, an - // entry is encountered which does not have its initial position between the - // entry to remove and the position looked at, then this entry can be moved to - // the place of the entry to remove without breaking the search for it. The - // entry made vacant by this move is now the entry to remove and the process - // starts over. - // Algorithm from http://en.wikipedia.org/wiki/Open_addressing. - - // This guarantees loop termination as there is at least one empty entry so - // eventually the removed entry will have an empty entry after it. - ASSERT(occupancy_ < capacity_); - - // p is the candidate entry to clear. q is used to scan forwards. - Entry* q = p; // Start at the entry to remove. - while (true) { - // Move q to the next entry. - q = q + 1; - if (q == map_end()) { - q = map_; - } - - // All entries between p and q have their initial position between p and q - // and the entry p can be cleared without breaking the search for these - // entries. - if (q->key == NULL) { - break; - } - - // Find the initial position for the entry at position q. - Entry* r = map_ + (q->hash & (capacity_ - 1)); - - // If the entry at position q has its initial position outside the range - // between p and q it can be moved forward to position p and will still be - // found. There is now a new candidate entry for clearing. - if ((q > p && (r <= p || r > q)) || - (q < p && (r <= p && r > q))) { - *p = *q; - p = q; - } - } - - // Clear the entry which is allowed to en emptied. - p->key = NULL; - occupancy_--; -} - - -void HashMap::Clear() { - // Mark all entries as empty. - const Entry* end = map_end(); - for (Entry* p = map_; p < end; p++) { - p->key = NULL; - } - occupancy_ = 0; -} - - -HashMap::Entry* HashMap::Start() const { - return Next(map_ - 1); -} - - -HashMap::Entry* HashMap::Next(Entry* p) const { - const Entry* end = map_end(); - ASSERT(map_ - 1 <= p && p < end); - for (p++; p < end; p++) { - if (p->key != NULL) { - return p; - } - } - return NULL; -} - - -HashMap::Entry* HashMap::Probe(void* key, uint32_t hash) { - ASSERT(key != NULL); - - ASSERT(IsPowerOf2(capacity_)); - Entry* p = map_ + (hash & (capacity_ - 1)); - const Entry* end = map_end(); - ASSERT(map_ <= p && p < end); - - ASSERT(occupancy_ < capacity_); // Guarantees loop termination. - while (p->key != NULL && (hash != p->hash || !match_(key, p->key))) { - p++; - if (p >= end) { - p = map_; - } - } - - return p; -} - - -void HashMap::Initialize(uint32_t capacity) { - ASSERT(IsPowerOf2(capacity)); - map_ = reinterpret_cast(allocator_->New(capacity * sizeof(Entry))); - if (map_ == NULL) { - v8::internal::FatalProcessOutOfMemory("HashMap::Initialize"); - return; - } - capacity_ = capacity; - Clear(); -} - - -void HashMap::Resize() { - Entry* map = map_; - uint32_t n = occupancy_; - - // Allocate larger map. - Initialize(capacity_ * 2); - - // Rehash all current entries. - for (Entry* p = map; n > 0; p++) { - if (p->key != NULL) { - Lookup(p->key, p->hash, true)->value = p->value; - n--; - } - } - - // Delete old map. - allocator_->Delete(map); -} - - -} } // namespace v8::internal diff --git a/deps/v8/src/hashmap.h b/deps/v8/src/hashmap.h index d2d1fafa32..ede098cfd0 100644 --- a/deps/v8/src/hashmap.h +++ b/deps/v8/src/hashmap.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// 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: @@ -29,34 +29,22 @@ #define V8_HASHMAP_H_ #include "allocation.h" +#include "checks.h" +#include "utils.h" namespace v8 { namespace internal { - -// Allocator defines the memory allocator interface -// used by HashMap and implements a default allocator. -class Allocator BASE_EMBEDDED { - public: - virtual ~Allocator() {} - virtual void* New(size_t size) { return Malloced::New(size); } - virtual void Delete(void* p) { Malloced::Delete(p); } -}; - - -class HashMap { +template +class TemplateHashMap { public: - static Allocator* DefaultAllocator; - typedef bool (*MatchFun) (void* key1, void* key2); // initial_capacity is the size of the initial hash map; // it must be a power of 2 (and thus must not be 0). - explicit HashMap(MatchFun match, - Allocator* allocator = DefaultAllocator, - uint32_t initial_capacity = 8); + TemplateHashMap(MatchFun match, uint32_t initial_capacity = 8); - ~HashMap(); + ~TemplateHashMap(); // HashMap entries are (key, value, hash) triplets. // Some clients may not need to use the value slot @@ -100,7 +88,6 @@ class HashMap { Entry* Next(Entry* p) const; private: - Allocator* allocator_; MatchFun match_; Entry* map_; uint32_t capacity_; @@ -112,6 +99,196 @@ class HashMap { void Resize(); }; +typedef TemplateHashMap HashMap; + +template +TemplateHashMap

::TemplateHashMap(MatchFun match, + uint32_t initial_capacity) { + match_ = match; + Initialize(initial_capacity); +} + + +template +TemplateHashMap

::~TemplateHashMap() { + P::Delete(map_); +} + + +template +typename TemplateHashMap

::Entry* TemplateHashMap

::Lookup( + void* key, uint32_t hash, bool insert) { + // Find a matching entry. + Entry* p = Probe(key, hash); + if (p->key != NULL) { + return p; + } + + // No entry found; insert one if necessary. + if (insert) { + p->key = key; + p->value = NULL; + p->hash = hash; + occupancy_++; + + // Grow the map if we reached >= 80% occupancy. + if (occupancy_ + occupancy_/4 >= capacity_) { + Resize(); + p = Probe(key, hash); + } + + return p; + } + + // No entry found and none inserted. + return NULL; +} + + +template +void TemplateHashMap

::Remove(void* key, uint32_t hash) { + // Lookup the entry for the key to remove. + Entry* p = Probe(key, hash); + if (p->key == NULL) { + // Key not found nothing to remove. + return; + } + + // To remove an entry we need to ensure that it does not create an empty + // entry that will cause the search for another entry to stop too soon. If all + // the entries between the entry to remove and the next empty slot have their + // initial position inside this interval, clearing the entry to remove will + // not break the search. If, while searching for the next empty entry, an + // entry is encountered which does not have its initial position between the + // entry to remove and the position looked at, then this entry can be moved to + // the place of the entry to remove without breaking the search for it. The + // entry made vacant by this move is now the entry to remove and the process + // starts over. + // Algorithm from http://en.wikipedia.org/wiki/Open_addressing. + + // This guarantees loop termination as there is at least one empty entry so + // eventually the removed entry will have an empty entry after it. + ASSERT(occupancy_ < capacity_); + + // p is the candidate entry to clear. q is used to scan forwards. + Entry* q = p; // Start at the entry to remove. + while (true) { + // Move q to the next entry. + q = q + 1; + if (q == map_end()) { + q = map_; + } + + // All entries between p and q have their initial position between p and q + // and the entry p can be cleared without breaking the search for these + // entries. + if (q->key == NULL) { + break; + } + + // Find the initial position for the entry at position q. + Entry* r = map_ + (q->hash & (capacity_ - 1)); + + // If the entry at position q has its initial position outside the range + // between p and q it can be moved forward to position p and will still be + // found. There is now a new candidate entry for clearing. + if ((q > p && (r <= p || r > q)) || + (q < p && (r <= p && r > q))) { + *p = *q; + p = q; + } + } + + // Clear the entry which is allowed to en emptied. + p->key = NULL; + occupancy_--; +} + + +template +void TemplateHashMap

::Clear() { + // Mark all entries as empty. + const Entry* end = map_end(); + for (Entry* p = map_; p < end; p++) { + p->key = NULL; + } + occupancy_ = 0; +} + + +template +typename TemplateHashMap

::Entry* TemplateHashMap

::Start() const { + return Next(map_ - 1); +} + + +template +typename TemplateHashMap

::Entry* TemplateHashMap

::Next(Entry* p) const { + const Entry* end = map_end(); + ASSERT(map_ - 1 <= p && p < end); + for (p++; p < end; p++) { + if (p->key != NULL) { + return p; + } + } + return NULL; +} + + +template +typename TemplateHashMap

::Entry* TemplateHashMap

::Probe(void* key, + uint32_t hash) { + ASSERT(key != NULL); + + ASSERT(IsPowerOf2(capacity_)); + Entry* p = map_ + (hash & (capacity_ - 1)); + const Entry* end = map_end(); + ASSERT(map_ <= p && p < end); + + ASSERT(occupancy_ < capacity_); // Guarantees loop termination. + while (p->key != NULL && (hash != p->hash || !match_(key, p->key))) { + p++; + if (p >= end) { + p = map_; + } + } + + return p; +} + + +template +void TemplateHashMap

::Initialize(uint32_t capacity) { + ASSERT(IsPowerOf2(capacity)); + map_ = reinterpret_cast(P::New(capacity * sizeof(Entry))); + if (map_ == NULL) { + v8::internal::FatalProcessOutOfMemory("HashMap::Initialize"); + return; + } + capacity_ = capacity; + Clear(); +} + + +template +void TemplateHashMap

::Resize() { + Entry* map = map_; + uint32_t n = occupancy_; + + // Allocate larger map. + Initialize(capacity_ * 2); + + // Rehash all current entries. + for (Entry* p = map; n > 0; p++) { + if (p->key != NULL) { + Lookup(p->key, p->hash, true)->value = p->value; + n--; + } + } + + // Delete old map. + P::Delete(map); +} } } // namespace v8::internal diff --git a/deps/v8/src/heap-inl.h b/deps/v8/src/heap-inl.h index 39cdf139e8..81ed448a17 100644 --- a/deps/v8/src/heap-inl.h +++ b/deps/v8/src/heap-inl.h @@ -49,7 +49,7 @@ void PromotionQueue::insert(HeapObject* target, int size) { NewSpacePage* rear_page = NewSpacePage::FromAddress(reinterpret_cast

(rear_)); ASSERT(!rear_page->prev_page()->is_anchor()); - rear_ = reinterpret_cast(rear_page->prev_page()->body_limit()); + rear_ = reinterpret_cast(rear_page->prev_page()->area_end()); ActivateGuardIfOnTheSamePage(); } @@ -81,11 +81,6 @@ void PromotionQueue::ActivateGuardIfOnTheSamePage() { } -int Heap::MaxObjectSizeInPagedSpace() { - return Page::kMaxHeapObjectSize; -} - - MaybeObject* Heap::AllocateStringFromUtf8(Vector str, PretenureFlag pretenure) { // Check for ASCII first since this is the common case. @@ -119,7 +114,7 @@ MaybeObject* Heap::AllocateAsciiSymbol(Vector str, // Allocate string. Object* result; - { MaybeObject* maybe_result = (size > MaxObjectSizeInPagedSpace()) + { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) : old_data_space_->AllocateRaw(size); if (!maybe_result->ToObject(&result)) return maybe_result; @@ -153,7 +148,7 @@ MaybeObject* Heap::AllocateTwoByteSymbol(Vector str, // Allocate string. Object* result; - { MaybeObject* maybe_result = (size > MaxObjectSizeInPagedSpace()) + { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) : old_data_space_->AllocateRaw(size); if (!maybe_result->ToObject(&result)) return maybe_result; diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc index 4c54e84f6c..e0b1e50f18 100644 --- a/deps/v8/src/heap.cc +++ b/deps/v8/src/heap.cc @@ -1092,7 +1092,7 @@ void PromotionQueue::RelocateQueueHead() { Page* p = Page::FromAllocationTop(reinterpret_cast
(rear_)); intptr_t* head_start = rear_; intptr_t* head_end = - Min(front_, reinterpret_cast(p->body_limit())); + Min(front_, reinterpret_cast(p->area_end())); int entries_count = static_cast(head_end - head_start) / kEntrySizeInWords; @@ -1435,7 +1435,7 @@ Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor, NewSpaceScavenger::IterateBody(object->map(), object); } else { new_space_front = - NewSpacePage::FromLimit(new_space_front)->next_page()->body(); + NewSpacePage::FromLimit(new_space_front)->next_page()->area_start(); } } @@ -1597,7 +1597,7 @@ class ScavengingVisitor : public StaticVisitorBase { HeapObject* object, int object_size) { SLOW_ASSERT((size_restriction != SMALL) || - (object_size <= Page::kMaxHeapObjectSize)); + (object_size <= Page::kMaxNonCodeHeapObjectSize)); SLOW_ASSERT(object->Size() == object_size); Heap* heap = map->GetHeap(); @@ -1605,7 +1605,7 @@ class ScavengingVisitor : public StaticVisitorBase { MaybeObject* maybe_result; if ((size_restriction != SMALL) && - (object_size > Page::kMaxHeapObjectSize)) { + (object_size > Page::kMaxNonCodeHeapObjectSize)) { maybe_result = heap->lo_space()->AllocateRaw(object_size, NOT_EXECUTABLE); } else { @@ -1951,6 +1951,16 @@ MaybeObject* Heap::AllocateTypeFeedbackInfo() { } +MaybeObject* Heap::AllocateAliasedArgumentsEntry(int aliased_context_slot) { + AliasedArgumentsEntry* entry; + { MaybeObject* maybe_result = AllocateStruct(ALIASED_ARGUMENTS_ENTRY_TYPE); + if (!maybe_result->To(&entry)) return maybe_result; + } + entry->set_aliased_context_slot(aliased_context_slot); + return entry; +} + + const Heap::StringTypeTable Heap::string_type_table[] = { #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ {type, size, k##camel_name##MapRootIndex}, @@ -2264,7 +2274,7 @@ bool Heap::CreateInitialMaps() { MaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { // Statically ensure that it is safe to allocate heap numbers in paged // spaces. - STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); + STATIC_ASSERT(HeapNumber::kSize <= Page::kNonCodeObjectAreaSize); AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; Object* result; @@ -2285,7 +2295,7 @@ MaybeObject* Heap::AllocateHeapNumber(double value) { // This version of AllocateHeapNumber is optimized for // allocation in new space. - STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); + STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxNonCodeHeapObjectSize); ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); Object* result; { MaybeObject* maybe_result = new_space_.AllocateRaw(HeapNumber::kSize); @@ -2856,7 +2866,7 @@ MaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) { MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) { // Statically ensure that it is safe to allocate foreigns in paged spaces. - STATIC_ASSERT(Foreign::kSize <= Page::kMaxHeapObjectSize); + STATIC_ASSERT(Foreign::kSize <= Page::kMaxNonCodeHeapObjectSize); AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; Foreign* result; MaybeObject* maybe_result = Allocate(foreign_map(), space); @@ -3274,7 +3284,7 @@ MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { } int size = ByteArray::SizeFor(length); Object* result; - { MaybeObject* maybe_result = (size <= MaxObjectSizeInPagedSpace()) + { MaybeObject* maybe_result = (size <= Page::kMaxNonCodeHeapObjectSize) ? old_data_space_->AllocateRaw(size) : lo_space_->AllocateRaw(size, NOT_EXECUTABLE); if (!maybe_result->ToObject(&result)) return maybe_result; @@ -3293,7 +3303,7 @@ MaybeObject* Heap::AllocateByteArray(int length) { } int size = ByteArray::SizeFor(length); AllocationSpace space = - (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : NEW_SPACE; + (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : NEW_SPACE; Object* result; { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); if (!maybe_result->ToObject(&result)) return maybe_result; @@ -3359,7 +3369,7 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc, MaybeObject* maybe_result; // Large code objects and code objects which should stay at a fixed address // are allocated in large object space. - if (obj_size > MaxObjectSizeInPagedSpace() || immovable) { + if (obj_size > code_space()->AreaSize() || immovable) { maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); } else { maybe_result = code_space_->AllocateRaw(obj_size); @@ -3408,7 +3418,7 @@ MaybeObject* Heap::CopyCode(Code* code) { // Allocate an object the same size as the code object. int obj_size = code->Size(); MaybeObject* maybe_result; - if (obj_size > MaxObjectSizeInPagedSpace()) { + if (obj_size > code_space()->AreaSize()) { maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); } else { maybe_result = code_space_->AllocateRaw(obj_size); @@ -3451,7 +3461,7 @@ MaybeObject* Heap::CopyCode(Code* code, Vector reloc_info) { static_cast(code->instruction_end() - old_addr); MaybeObject* maybe_result; - if (new_obj_size > MaxObjectSizeInPagedSpace()) { + if (new_obj_size > code_space()->AreaSize()) { maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); } else { maybe_result = code_space_->AllocateRaw(new_obj_size); @@ -3772,7 +3782,7 @@ MaybeObject* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) { // Allocate the JSObject. AllocationSpace space = (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; - if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE; + if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; Object* obj; { MaybeObject* maybe_obj = Allocate(map, space); if (!maybe_obj->ToObject(&obj)) return maybe_obj; @@ -4280,7 +4290,7 @@ MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer, // Allocate string. Object* result; - { MaybeObject* maybe_result = (size > MaxObjectSizeInPagedSpace()) + { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) : old_data_space_->AllocateRaw(size); if (!maybe_result->ToObject(&result)) return maybe_result; @@ -4317,11 +4327,12 @@ MaybeObject* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { if (size > kMaxObjectSizeInNewSpace) { // Allocate in large object space, retry space will be ignored. space = LO_SPACE; - } else if (size > MaxObjectSizeInPagedSpace()) { + } else if (size > Page::kMaxNonCodeHeapObjectSize) { // Allocate in new space, retry in large object space. retry_space = LO_SPACE; } - } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { + } else if (space == OLD_DATA_SPACE && + size > Page::kMaxNonCodeHeapObjectSize) { space = LO_SPACE; } Object* result; @@ -4352,11 +4363,12 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length, if (size > kMaxObjectSizeInNewSpace) { // Allocate in large object space, retry space will be ignored. space = LO_SPACE; - } else if (size > MaxObjectSizeInPagedSpace()) { + } else if (size > Page::kMaxNonCodeHeapObjectSize) { // Allocate in new space, retry in large object space. retry_space = LO_SPACE; } - } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { + } else if (space == OLD_DATA_SPACE && + size > Page::kMaxNonCodeHeapObjectSize) { space = LO_SPACE; } Object* result; @@ -4495,13 +4507,13 @@ MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) { // Too big for new space. space = LO_SPACE; } else if (space == OLD_POINTER_SPACE && - size > MaxObjectSizeInPagedSpace()) { + size > Page::kMaxNonCodeHeapObjectSize) { // Too big for old pointer space. space = LO_SPACE; } AllocationSpace retry_space = - (size <= MaxObjectSizeInPagedSpace()) ? OLD_POINTER_SPACE : LO_SPACE; + (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_POINTER_SPACE : LO_SPACE; return AllocateRaw(size, space, retry_space); } @@ -4628,13 +4640,13 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, // Too big for new space. space = LO_SPACE; } else if (space == OLD_DATA_SPACE && - size > MaxObjectSizeInPagedSpace()) { + size > Page::kMaxNonCodeHeapObjectSize) { // Too big for old data space. space = LO_SPACE; } AllocationSpace retry_space = - (size <= MaxObjectSizeInPagedSpace()) ? OLD_DATA_SPACE : LO_SPACE; + (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_DATA_SPACE : LO_SPACE; return AllocateRaw(size, space, retry_space); } @@ -4763,7 +4775,7 @@ STRUCT_LIST(MAKE_CASE) } int size = map->instance_size(); AllocationSpace space = - (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE; + (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : OLD_POINTER_SPACE; Object* result; { MaybeObject* maybe_result = Allocate(map, space); if (!maybe_result->ToObject(&result)) return maybe_result; @@ -5210,7 +5222,7 @@ void Heap::ZapFromSpace() { new_space_.FromSpaceEnd()); while (it.has_next()) { NewSpacePage* page = it.next(); - for (Address cursor = page->body(), limit = page->body_limit(); + for (Address cursor = page->area_start(), limit = page->area_end(); cursor < limit; cursor += kPointerSize) { Memory::Address_at(cursor) = kFromSpaceZapValue; @@ -5349,9 +5361,9 @@ void Heap::OldPointerSpaceCheckStoreBuffer() { while (pages.has_next()) { Page* page = pages.next(); - Object** current = reinterpret_cast(page->ObjectAreaStart()); + Object** current = reinterpret_cast(page->area_start()); - Address end = page->ObjectAreaEnd(); + Address end = page->area_end(); Object*** store_buffer_position = store_buffer()->Start(); Object*** store_buffer_top = store_buffer()->Top(); @@ -5377,9 +5389,9 @@ void Heap::MapSpaceCheckStoreBuffer() { while (pages.has_next()) { Page* page = pages.next(); - Object** current = reinterpret_cast(page->ObjectAreaStart()); + Object** current = reinterpret_cast(page->area_start()); - Address end = page->ObjectAreaEnd(); + Address end = page->area_end(); Object*** store_buffer_position = store_buffer()->Start(); Object*** store_buffer_top = store_buffer()->Top(); diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h index bb5c37562e..70c3146be2 100644 --- a/deps/v8/src/heap.h +++ b/deps/v8/src/heap.h @@ -177,6 +177,7 @@ namespace internal { V(eval_symbol, "eval") \ V(function_symbol, "function") \ V(length_symbol, "length") \ + V(module_symbol, "module") \ V(name_symbol, "name") \ V(native_symbol, "native") \ V(null_symbol, "null") \ @@ -345,7 +346,7 @@ class PromotionQueue { NewSpacePage::FromAddress(reinterpret_cast
(front_)); ASSERT(!front_page->prev_page()->is_anchor()); front_ = - reinterpret_cast(front_page->prev_page()->body_limit()); + reinterpret_cast(front_page->prev_page()->area_end()); } *target = reinterpret_cast(*(--front_)); *size = static_cast(*(--front_)); @@ -484,9 +485,6 @@ class Heap { // all available bytes. Check MaxHeapObjectSize() instead. intptr_t Available(); - // Returns the maximum object size in paged space. - inline int MaxObjectSizeInPagedSpace(); - // Returns of size of all objects residing in the heap. intptr_t SizeOfObjects(); @@ -644,6 +642,9 @@ class Heap { // Allocates an empty TypeFeedbackInfo. MUST_USE_RESULT MaybeObject* AllocateTypeFeedbackInfo(); + // Allocates an AliasedArgumentsEntry. + MUST_USE_RESULT MaybeObject* AllocateAliasedArgumentsEntry(int slot); + // Clear the Instanceof cache (used when a prototype changes). inline void ClearInstanceofCache(); diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index c59c9e4f94..6cd9998b67 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -276,6 +276,15 @@ bool HValue::IsDefinedAfter(HBasicBlock* other) const { } +HUseListNode* HUseListNode::tail() { + // Skip and remove dead items in the use list. + while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) { + tail_ = tail_->tail_; + } + return tail_; +} + + HUseIterator::HUseIterator(HUseListNode* head) : next_(head) { Advance(); } @@ -374,7 +383,7 @@ void HValue::DeleteAndReplaceWith(HValue* other) { // We replace all uses first, so Delete can assert that there are none. if (other != NULL) ReplaceAllUsesWith(other); ASSERT(HasNoUses()); - ClearOperands(); + Kill(); DeleteFromGraph(); } @@ -392,9 +401,17 @@ void HValue::ReplaceAllUsesWith(HValue* other) { } -void HValue::ClearOperands() { +void HValue::Kill() { + // Instead of going through the entire use list of each operand, we only + // check the first item in each use list and rely on the tail() method to + // skip dead items, removing them lazily next time we traverse the list. + SetFlag(kIsDead); for (int i = 0; i < OperandCount(); ++i) { - SetOperandAt(i, NULL); + HValue* operand = OperandAt(i); + HUseListNode* first = operand->use_list_; + if (first != NULL && first->value() == this && first->index() == i) { + operand->use_list_ = first->tail(); + } } } diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h index 4d7b7baa88..92645a2b31 100644 --- a/deps/v8/src/hydrogen-instructions.h +++ b/deps/v8/src/hydrogen-instructions.h @@ -448,7 +448,7 @@ class HUseListNode: public ZoneObject { : tail_(tail), value_(value), index_(index) { } - HUseListNode* tail() const { return tail_; } + HUseListNode* tail(); HValue* value() const { return value_; } int index() const { return index_; } @@ -530,7 +530,8 @@ class HValue: public ZoneObject { kDeoptimizeOnUndefined, kIsArguments, kTruncatingToInt32, - kLastFlag = kTruncatingToInt32 + kIsDead, + kLastFlag = kIsDead }; STATIC_ASSERT(kLastFlag < kBitsPerInt); @@ -630,7 +631,9 @@ class HValue: public ZoneObject { return use_list_ != NULL && use_list_->tail() != NULL; } int UseCount() const; - void ClearOperands(); + + // Mark this HValue as dead and to be removed from other HValues' use lists. + void Kill(); int flags() const { return flags_; } void SetFlag(Flag f) { flags_ |= (1 << f); } @@ -2454,7 +2457,12 @@ class HConstant: public HTemplateInstruction<0> { virtual intptr_t Hashcode() { ASSERT(!HEAP->allow_allocation(false)); - return reinterpret_cast(*handle()); + intptr_t hash = reinterpret_cast(*handle()); + // Prevent smis from having fewer hash values when truncated to + // the least significant bits. + const int kShiftSize = kSmiShiftSize + kSmiTagSize; + STATIC_ASSERT(kShiftSize != 0); + return hash ^ (hash >> kShiftSize); } #ifdef DEBUG diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc index 9918e85180..4908586f7c 100644 --- a/deps/v8/src/hydrogen.cc +++ b/deps/v8/src/hydrogen.cc @@ -97,7 +97,7 @@ void HBasicBlock::RemovePhi(HPhi* phi) { ASSERT(phi->block() == this); ASSERT(phis_.Contains(phi)); ASSERT(phi->HasNoUses() || !phi->is_live()); - phi->ClearOperands(); + phi->Kill(); phis_.RemoveElement(phi); phi->SetBlock(NULL); } @@ -3242,6 +3242,10 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { ASSERT(current_block() != NULL); ASSERT(current_block()->HasPredecessor()); + if (!FLAG_optimize_for_in) { + return Bailout("ForInStatement optimization is disabled"); + } + if (!stmt->each()->IsVariableProxy() || !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { return Bailout("ForInStatement with non-local each variable"); diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc index 469ead9510..ee1462567c 100644 --- a/deps/v8/src/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/ia32/full-codegen-ia32.cc @@ -100,6 +100,11 @@ class JumpPatchSite BASE_EMBEDDED { }; +int FullCodeGenerator::self_optimization_header_size() { + return 13; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right, with the // return address on top of them. The actual argument count matches the @@ -122,13 +127,6 @@ void FullCodeGenerator::Generate() { SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); -#ifdef DEBUG - if (strlen(FLAG_stop_at) > 0 && - info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { - __ int3(); - } -#endif - // We can optionally optimize based on counters rather than statistical // sampling. if (info->ShouldSelfOptimize()) { @@ -136,6 +134,7 @@ void FullCodeGenerator::Generate() { PrintF("[adding self-optimization header to %s]\n", *info->function()->debug_name()->ToCString()); } + has_self_optimization_header_ = true; MaybeObject* maybe_cell = isolate()->heap()->AllocateJSGlobalPropertyCell( Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt)); JSGlobalPropertyCell* cell; @@ -146,9 +145,17 @@ void FullCodeGenerator::Generate() { isolate()->builtins()->builtin(Builtins::kLazyRecompile)); STATIC_ASSERT(kSmiTag == 0); __ j(zero, compile_stub); + ASSERT(masm_->pc_offset() == self_optimization_header_size()); } } +#ifdef DEBUG + if (strlen(FLAG_stop_at) > 0 && + info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { + __ int3(); + } +#endif + // Strict mode functions and builtins need to replace the receiver // with undefined when called as functions (without an explicit // receiver object). ecx is zero for method calls and non-zero for @@ -335,7 +342,15 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt, int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); weight = Min(127, Max(1, distance / 100)); } - __ sub(Operand::Cell(profiling_counter_), Immediate(Smi::FromInt(weight))); + if (Serializer::enabled()) { + __ mov(ebx, Immediate(profiling_counter_)); + __ sub(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), + Immediate(Smi::FromInt(weight))); + } else { + // This version is slightly faster, but not snapshot safe. + __ sub(Operand::Cell(profiling_counter_), + Immediate(Smi::FromInt(weight))); + } __ j(positive, &ok, Label::kNear); InterruptStub stub; __ CallStub(&stub); @@ -365,8 +380,14 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt, if (FLAG_count_based_interrupts) { // Reset the countdown. - __ mov(Operand::Cell(profiling_counter_), - Immediate(Smi::FromInt(FLAG_interrupt_budget))); + if (Serializer::enabled()) { + __ mov(ebx, Immediate(profiling_counter_)); + __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), + Immediate(Smi::FromInt(FLAG_interrupt_budget))); + } else { + __ mov(Operand::Cell(profiling_counter_), + Immediate(Smi::FromInt(FLAG_interrupt_budget))); + } } __ bind(&ok); @@ -396,8 +417,15 @@ void FullCodeGenerator::EmitReturnSequence() { int distance = masm_->pc_offset(); weight = Min(127, Max(1, distance / 100)); } - __ sub(Operand::Cell(profiling_counter_), - Immediate(Smi::FromInt(weight))); + if (Serializer::enabled()) { + __ mov(ebx, Immediate(profiling_counter_)); + __ sub(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), + Immediate(Smi::FromInt(weight))); + } else { + // This version is slightly faster, but not snapshot safe. + __ sub(Operand::Cell(profiling_counter_), + Immediate(Smi::FromInt(weight))); + } Label ok; __ j(positive, &ok, Label::kNear); __ push(eax); @@ -405,8 +433,14 @@ void FullCodeGenerator::EmitReturnSequence() { __ CallStub(&stub); __ pop(eax); // Reset the countdown. - __ mov(Operand::Cell(profiling_counter_), - Immediate(Smi::FromInt(FLAG_interrupt_budget))); + if (Serializer::enabled()) { + __ mov(ebx, Immediate(profiling_counter_)); + __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), + Immediate(Smi::FromInt(FLAG_interrupt_budget))); + } else { + __ mov(Operand::Cell(profiling_counter_), + Immediate(Smi::FromInt(FLAG_interrupt_budget))); + } __ bind(&ok); } #ifdef DEBUG diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc index 120ab14f80..32704b04e5 100644 --- a/deps/v8/src/ia32/lithium-ia32.cc +++ b/deps/v8/src/ia32/lithium-ia32.cc @@ -1935,13 +1935,14 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( HLoadNamedFieldPolymorphic* instr) { ASSERT(instr->representation().IsTagged()); - LOperand* context = UseFixed(instr->context(), esi); if (instr->need_generic()) { + LOperand* context = UseFixed(instr->context(), esi); LOperand* obj = UseFixed(instr->object(), eax); LLoadNamedFieldPolymorphic* result = new(zone()) LLoadNamedFieldPolymorphic(context, obj); return MarkAsCall(DefineFixed(result, eax), instr); } else { + LOperand* context = UseAny(instr->context()); // Not actually used. LOperand* obj = UseRegisterAtStart(instr->object()); LLoadNamedFieldPolymorphic* result = new(zone()) LLoadNamedFieldPolymorphic(context, obj); diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc index 642a9e2731..9bea13b948 100644 --- a/deps/v8/src/ic.cc +++ b/deps/v8/src/ic.cc @@ -315,10 +315,13 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) { if (delta != 0) { Code* host = target->GetHeap()->isolate()-> inner_pointer_to_code_cache()->GetCacheEntry(address)->code; - TypeFeedbackInfo* info = - TypeFeedbackInfo::cast(host->type_feedback_info()); - info->set_ic_with_typeinfo_count( - info->ic_with_typeinfo_count() + delta); + // Not all Code objects have TypeFeedbackInfo. + if (host->type_feedback_info()->IsTypeFeedbackInfo()) { + TypeFeedbackInfo* info = + TypeFeedbackInfo::cast(host->type_feedback_info()); + info->set_ic_with_typeinfo_count( + info->ic_with_typeinfo_count() + delta); + } } } } @@ -1329,7 +1332,7 @@ MaybeObject* StoreIC::Store(State state, uint32_t index; if (name->AsArrayIndex(&index)) { Handle result = - JSObject::SetElement(receiver, index, value, strict_mode); + JSObject::SetElement(receiver, index, value, NONE, strict_mode); RETURN_IF_EMPTY_HANDLE(isolate(), result); return *value; } @@ -1786,7 +1789,7 @@ MaybeObject* KeyedStoreIC::Store(State state, uint32_t index; if (name->AsArrayIndex(&index)) { Handle result = - JSObject::SetElement(receiver, index, value, strict_mode); + JSObject::SetElement(receiver, index, value, NONE, strict_mode); RETURN_IF_EMPTY_HANDLE(isolate(), result); return *value; } diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h index 80edee9c7b..71fe8838f8 100644 --- a/deps/v8/src/isolate.h +++ b/deps/v8/src/isolate.h @@ -38,6 +38,7 @@ #include "frames.h" #include "global-handles.h" #include "handles.h" +#include "hashmap.h" #include "heap.h" #include "regexp-stack.h" #include "runtime-profiler.h" @@ -280,23 +281,6 @@ class ThreadLocalTop BASE_EMBEDDED { Address try_catch_handler_address_; }; -#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) - -#define ISOLATE_PLATFORM_INIT_LIST(V) \ - /* VirtualFrame::SpilledScope state */ \ - V(bool, is_virtual_frame_in_spilled_scope, false) \ - /* CodeGenerator::EmitNamedStore state */ \ - V(int, inlined_write_barrier_size, -1) - -#if !defined(__arm__) && !defined(__mips__) -class HashMap; -#endif - -#else - -#define ISOLATE_PLATFORM_INIT_LIST(V) - -#endif #ifdef ENABLE_DEBUGGER_SUPPORT @@ -367,7 +351,6 @@ typedef List DebugObjectCache; V(uint64_t, enabled_cpu_features, 0) \ V(CpuProfiler*, cpu_profiler, NULL) \ V(HeapProfiler*, heap_profiler, NULL) \ - ISOLATE_PLATFORM_INIT_LIST(V) \ ISOLATE_DEBUGGER_INIT_LIST(V) class Isolate { diff --git a/deps/v8/src/liveedit.cc b/deps/v8/src/liveedit.cc index 5ff8ff9d3b..9c5294a26d 100644 --- a/deps/v8/src/liveedit.cc +++ b/deps/v8/src/liveedit.cc @@ -53,8 +53,8 @@ void SetElementNonStrict(Handle object, // Ignore return value from SetElement. It can only be a failure if there // are element setters causing exceptions and the debugger context has none // of these. - Handle no_failure; - no_failure = JSObject::SetElement(object, index, value, kNonStrictMode); + Handle no_failure = + JSObject::SetElement(object, index, value, NONE, kNonStrictMode); ASSERT(!no_failure.is_null()); USE(no_failure); } diff --git a/deps/v8/src/log.h b/deps/v8/src/log.h index 86bcad69aa..e54f0413e9 100644 --- a/deps/v8/src/log.h +++ b/deps/v8/src/log.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// 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: @@ -71,7 +71,6 @@ namespace internal { // tick profiler requires code events, so --prof implies --log-code. // Forward declarations. -class HashMap; class LogMessageBuilder; class Profiler; class Semaphore; diff --git a/deps/v8/src/mark-compact.cc b/deps/v8/src/mark-compact.cc index 9d83d90fbf..7c59c0471e 100644 --- a/deps/v8/src/mark-compact.cc +++ b/deps/v8/src/mark-compact.cc @@ -107,14 +107,14 @@ static void VerifyMarking(NewSpace* space) { Address end = space->top(); NewSpacePageIterator it(space->bottom(), end); // The bottom position is at the start of its page. Allows us to use - // page->body() as start of range on all pages. + // page->area_start() as start of range on all pages. ASSERT_EQ(space->bottom(), - NewSpacePage::FromAddress(space->bottom())->body()); + NewSpacePage::FromAddress(space->bottom())->area_start()); while (it.has_next()) { NewSpacePage* page = it.next(); - Address limit = it.has_next() ? page->body_limit() : end; + Address limit = it.has_next() ? page->area_end() : end; ASSERT(limit == end || !page->Contains(end)); - VerifyMarking(page->body(), limit); + VerifyMarking(page->area_start(), limit); } } @@ -124,7 +124,7 @@ static void VerifyMarking(PagedSpace* space) { while (it.has_next()) { Page* p = it.next(); - VerifyMarking(p->ObjectAreaStart(), p->ObjectAreaEnd()); + VerifyMarking(p->area_start(), p->area_end()); } } @@ -187,8 +187,8 @@ static void VerifyEvacuation(NewSpace* space) { while (it.has_next()) { NewSpacePage* page = it.next(); - Address current = page->body(); - Address limit = it.has_next() ? page->body_limit() : space->top(); + Address current = page->area_start(); + Address limit = it.has_next() ? page->area_end() : space->top(); ASSERT(limit == space->top() || !page->Contains(space->top())); while (current < limit) { HeapObject* object = HeapObject::FromAddress(current); @@ -205,7 +205,7 @@ static void VerifyEvacuation(PagedSpace* space) { while (it.has_next()) { Page* p = it.next(); if (p->IsEvacuationCandidate()) continue; - VerifyEvacuation(p->ObjectAreaStart(), p->ObjectAreaEnd()); + VerifyEvacuation(p->area_start(), p->area_end()); } } @@ -232,7 +232,7 @@ void MarkCompactCollector::AddEvacuationCandidate(Page* p) { static void TraceFragmentation(PagedSpace* space) { int number_of_pages = space->CountTotalPages(); - intptr_t reserved = (number_of_pages * Page::kObjectAreaSize); + intptr_t reserved = (number_of_pages * space->AreaSize()); intptr_t free = reserved - space->SizeOfObjects(); PrintF("[%s]: %d pages, %d (%.1f%%) free\n", AllocationSpaceName(space->identity()), @@ -453,13 +453,14 @@ static int FreeListFragmentation(PagedSpace* space, Page* p) { intptr_t ratio; intptr_t ratio_threshold; + intptr_t area_size = space->AreaSize(); if (space->identity() == CODE_SPACE) { ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / - Page::kObjectAreaSize; + area_size; ratio_threshold = 10; } else { ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / - Page::kObjectAreaSize; + area_size; ratio_threshold = 15; } @@ -469,20 +470,20 @@ static int FreeListFragmentation(PagedSpace* space, Page* p) { AllocationSpaceName(space->identity()), static_cast(sizes.small_size_), static_cast(sizes.small_size_ * 100) / - Page::kObjectAreaSize, + area_size, static_cast(sizes.medium_size_), static_cast(sizes.medium_size_ * 100) / - Page::kObjectAreaSize, + area_size, static_cast(sizes.large_size_), static_cast(sizes.large_size_ * 100) / - Page::kObjectAreaSize, + area_size, static_cast(sizes.huge_size_), static_cast(sizes.huge_size_ * 100) / - Page::kObjectAreaSize, + area_size, (ratio > ratio_threshold) ? "[fragmented]" : ""); } - if (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize) { + if (FLAG_always_compact && sizes.Total() != area_size) { return 1; } @@ -528,11 +529,11 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { CompactionMode mode = COMPACT_FREE_LISTS; - intptr_t reserved = number_of_pages * Page::kObjectAreaSize; + intptr_t reserved = number_of_pages * space->AreaSize(); intptr_t over_reserved = reserved - space->SizeOfObjects(); static const intptr_t kFreenessThreshold = 50; - if (over_reserved >= 2 * Page::kObjectAreaSize && + if (over_reserved >= 2 * space->AreaSize() && reduce_memory_footprint_) { mode = REDUCE_MEMORY_FOOTPRINT; @@ -575,18 +576,17 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { intptr_t free_bytes = 0; if (!p->WasSwept()) { - free_bytes = (Page::kObjectAreaSize - p->LiveBytes()); + free_bytes = (p->area_size() - p->LiveBytes()); } else { FreeList::SizeStats sizes; space->CountFreeListItems(p, &sizes); free_bytes = sizes.Total(); } - int free_pct = static_cast(free_bytes * 100 / Page::kObjectAreaSize); + int free_pct = static_cast(free_bytes * 100) / p->area_size(); if (free_pct >= kFreenessThreshold) { - estimated_release += Page::kObjectAreaSize + - (Page::kObjectAreaSize - free_bytes); + estimated_release += 2 * p->area_size() - free_bytes; fragmentation = free_pct; } else { fragmentation = 0; @@ -597,7 +597,7 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { reinterpret_cast(p), AllocationSpaceName(space->identity()), static_cast(free_bytes), - static_cast(free_bytes * 100) / Page::kObjectAreaSize, + static_cast(free_bytes * 100) / p->area_size(), (fragmentation > 0) ? "[fragmented]" : ""); } } else { @@ -1977,12 +1977,15 @@ static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, Page* p) { int last_cell_index = Bitmap::IndexToCell( Bitmap::CellAlignIndex( - p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); + p->AddressToMarkbitIndex(p->area_end()))); + + Address cell_base = p->area_start(); + int cell_index = Bitmap::IndexToCell( + Bitmap::CellAlignIndex( + p->AddressToMarkbitIndex(cell_base))); - int cell_index = Page::kFirstUsedCell; - Address cell_base = p->ObjectAreaStart(); - for (cell_index = Page::kFirstUsedCell; + for (; cell_index < last_cell_index; cell_index++, cell_base += 32 * kPointerSize) { ASSERT((unsigned)cell_index == @@ -2786,7 +2789,7 @@ bool MarkCompactCollector::TryPromoteObject(HeapObject* object, int object_size) { Object* result; - if (object_size > heap()->MaxObjectSizeInPagedSpace()) { + if (object_size > Page::kMaxNonCodeHeapObjectSize) { MaybeObject* maybe_result = heap()->lo_space()->AllocateRaw(object_size, NOT_EXECUTABLE); if (maybe_result->ToObject(&result)) { @@ -2904,13 +2907,16 @@ void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { int last_cell_index = Bitmap::IndexToCell( Bitmap::CellAlignIndex( - p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); + p->AddressToMarkbitIndex(p->area_end()))); + + Address cell_base = p->area_start(); + int cell_index = Bitmap::IndexToCell( + Bitmap::CellAlignIndex( + p->AddressToMarkbitIndex(cell_base))); - int cell_index = Page::kFirstUsedCell; - Address cell_base = p->ObjectAreaStart(); int offsets[16]; - for (cell_index = Page::kFirstUsedCell; + for (; cell_index < last_cell_index; cell_index++, cell_base += 32 * kPointerSize) { ASSERT((unsigned)cell_index == @@ -3065,12 +3071,16 @@ static void SweepPrecisely(PagedSpace* space, int last_cell_index = Bitmap::IndexToCell( Bitmap::CellAlignIndex( - p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); + p->AddressToMarkbitIndex(p->area_end()))); + + Address free_start = p->area_start(); + int cell_index = + Bitmap::IndexToCell( + Bitmap::CellAlignIndex( + p->AddressToMarkbitIndex(free_start))); - int cell_index = Page::kFirstUsedCell; - Address free_start = p->ObjectAreaStart(); ASSERT(reinterpret_cast(free_start) % (32 * kPointerSize) == 0); - Address object_address = p->ObjectAreaStart(); + Address object_address = free_start; int offsets[16]; SkipList* skip_list = p->skip_list(); @@ -3079,7 +3089,7 @@ static void SweepPrecisely(PagedSpace* space, skip_list->Clear(); } - for (cell_index = Page::kFirstUsedCell; + for (; cell_index < last_cell_index; cell_index++, object_address += 32 * kPointerSize) { ASSERT((unsigned)cell_index == @@ -3116,8 +3126,8 @@ static void SweepPrecisely(PagedSpace* space, // Clear marking bits for current cell. cells[cell_index] = 0; } - if (free_start != p->ObjectAreaEnd()) { - space->Free(free_start, static_cast(p->ObjectAreaEnd() - free_start)); + if (free_start != p->area_end()) { + space->Free(free_start, static_cast(p->area_end() - free_start)); } p->ResetLiveBytes(); } @@ -3412,7 +3422,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { Page* p = evacuation_candidates_[i]; if (!p->IsEvacuationCandidate()) continue; PagedSpace* space = static_cast(p->owner()); - space->Free(p->ObjectAreaStart(), Page::kObjectAreaSize); + space->Free(p->area_start(), p->area_size()); p->set_scan_on_scavenge(false); slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); p->ClearEvacuationCandidate(); @@ -3715,23 +3725,27 @@ intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { int last_cell_index = Bitmap::IndexToCell( Bitmap::CellAlignIndex( - p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); + p->AddressToMarkbitIndex(p->area_end()))); + + int cell_index = + Bitmap::IndexToCell( + Bitmap::CellAlignIndex( + p->AddressToMarkbitIndex(p->area_start()))); - int cell_index = Page::kFirstUsedCell; intptr_t freed_bytes = 0; // This is the start of the 32 word block that we are currently looking at. - Address block_address = p->ObjectAreaStart(); + Address block_address = p->area_start(); // Skip over all the dead objects at the start of the page and mark them free. - for (cell_index = Page::kFirstUsedCell; + for (; cell_index < last_cell_index; cell_index++, block_address += 32 * kPointerSize) { if (cells[cell_index] != 0) break; } - size_t size = block_address - p->ObjectAreaStart(); + size_t size = block_address - p->area_start(); if (cell_index == last_cell_index) { - freed_bytes += static_cast(space->Free(p->ObjectAreaStart(), + freed_bytes += static_cast(space->Free(p->area_start(), static_cast(size))); ASSERT_EQ(0, p->LiveBytes()); return freed_bytes; @@ -3740,8 +3754,8 @@ intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { // first live object. Address free_end = StartOfLiveObject(block_address, cells[cell_index]); // Free the first free space. - size = free_end - p->ObjectAreaStart(); - freed_bytes += space->Free(p->ObjectAreaStart(), + size = free_end - p->area_start(); + freed_bytes += space->Free(p->area_start(), static_cast(size)); // The start of the current free area is represented in undigested form by // the address of the last 32-word section that contained a live object and diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc index fd0f487978..c8239e3246 100644 --- a/deps/v8/src/mips/full-codegen-mips.cc +++ b/deps/v8/src/mips/full-codegen-mips.cc @@ -119,6 +119,11 @@ class JumpPatchSite BASE_EMBEDDED { }; +int FullCodeGenerator::self_optimization_header_size() { + return 0; // TODO(jkummerow): determine correct value. +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right. The actual // argument count matches the formal parameter count expected by the @@ -140,13 +145,6 @@ void FullCodeGenerator::Generate() { SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); -#ifdef DEBUG - if (strlen(FLAG_stop_at) > 0 && - info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { - __ stop("stop-at"); - } -#endif - // We can optionally optimize based on counters rather than statistical // sampling. if (info->ShouldSelfOptimize()) { @@ -154,6 +152,7 @@ void FullCodeGenerator::Generate() { PrintF("[adding self-optimization header to %s]\n", *info->function()->debug_name()->ToCString()); } + has_self_optimization_header_ = true; MaybeObject* maybe_cell = isolate()->heap()->AllocateJSGlobalPropertyCell( Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt)); JSGlobalPropertyCell* cell; @@ -165,9 +164,17 @@ void FullCodeGenerator::Generate() { Handle compile_stub( isolate()->builtins()->builtin(Builtins::kLazyRecompile)); __ Jump(compile_stub, RelocInfo::CODE_TARGET, eq, a3, Operand(zero_reg)); + ASSERT(masm_->pc_offset() == self_optimization_header_size()); } } +#ifdef DEBUG + if (strlen(FLAG_stop_at) > 0 && + info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { + __ stop("stop-at"); + } +#endif + // Strict mode functions and builtins need to replace the receiver // with undefined when called as functions (without an explicit // receiver object). t1 is zero for method calls and non-zero for diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc index 6f009970da..7aef91215d 100644 --- a/deps/v8/src/objects-debug.cc +++ b/deps/v8/src/objects-debug.cc @@ -333,6 +333,11 @@ void TypeFeedbackInfo::TypeFeedbackInfoVerify() { } +void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() { + VerifySmiField(kAliasedContextSlot); +} + + void FixedArray::FixedArrayVerify() { for (int i = 0; i < length(); i++) { Object* e = get(i); diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 326c088e04..bc6217ba5e 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -3089,6 +3089,21 @@ void Code::set_compiled_optimizable(bool value) { } +bool Code::has_self_optimization_header() { + ASSERT(kind() == FUNCTION); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + return FullCodeFlagsHasSelfOptimizationHeader::decode(flags); +} + + +void Code::set_self_optimization_header(bool value) { + ASSERT(kind() == FUNCTION); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + flags = FullCodeFlagsHasSelfOptimizationHeader::update(flags, value); + WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); +} + + int Code::allow_osr_at_loop_nesting_level() { ASSERT(kind() == FUNCTION); return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset); @@ -3331,7 +3346,7 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) { DescriptorArray* Map::instance_descriptors() { Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); if (object->IsSmi()) { - return HEAP->empty_descriptor_array(); + return GetHeap()->empty_descriptor_array(); } else { return DescriptorArray::cast(object); } @@ -3645,7 +3660,7 @@ BOOL_ACCESSORS(SharedFunctionInfo, bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() { - return initial_map() != HEAP->undefined_value(); + return initial_map() != GetHeap()->undefined_value(); } @@ -4806,6 +4821,9 @@ ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells, kTypeFeedbackCellsOffset) +SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot) + + Relocatable::Relocatable(Isolate* isolate) { ASSERT(isolate == Isolate::Current()); isolate_ = isolate; diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc index d6e8920838..d5c02f4321 100644 --- a/deps/v8/src/objects-printer.cc +++ b/deps/v8/src/objects-printer.cc @@ -563,6 +563,12 @@ void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) { } +void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(FILE* out) { + HeapObject::PrintHeader(out, "AliasedArgumentsEntry"); + PrintF(out, "\n - aliased_context_slot: %d", aliased_context_slot()); +} + + void FixedArray::FixedArrayPrint(FILE* out) { HeapObject::PrintHeader(out, "FixedArray"); PrintF(out, " - length: %d", length()); diff --git a/deps/v8/src/objects-visiting.h b/deps/v8/src/objects-visiting.h index e6ddfed4a7..26e79ae5ed 100644 --- a/deps/v8/src/objects-visiting.h +++ b/deps/v8/src/objects-visiting.h @@ -135,7 +135,7 @@ class StaticVisitorBase : public AllStatic { (base == kVisitJSObject)); ASSERT(IsAligned(object_size, kPointerSize)); ASSERT(kMinObjectSizeInWords * kPointerSize <= object_size); - ASSERT(object_size < Page::kMaxHeapObjectSize); + ASSERT(object_size < Page::kMaxNonCodeHeapObjectSize); const VisitorId specialization = static_cast( base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index 85ba646005..8941151c0c 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -4450,10 +4450,7 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, } accessors->set(is_getter, fun); - { MaybeObject* maybe_ok = SetElementCallback(index, accessors, attributes); - if (maybe_ok->IsFailure()) return maybe_ok; - } - return GetHeap()->undefined_value(); + return SetElementCallback(index, accessors, attributes); } @@ -4471,12 +4468,14 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name, Object* obj = result.GetCallbackObject(); // Need to preserve old getters/setters. if (obj->IsAccessorPair()) { - AccessorPair::cast(obj)->set(is_getter, fun); - // Use set to update attributes. - { MaybeObject* maybe_ok = SetPropertyCallback(name, obj, attributes); - if (maybe_ok->IsFailure()) return maybe_ok; + AccessorPair* copy; + { MaybeObject* maybe_copy = + AccessorPair::cast(obj)->CopyWithoutTransitions(); + if (!maybe_copy->To(©)) return maybe_copy; } - return GetHeap()->undefined_value(); + copy->set(is_getter, fun); + // Use set to update attributes. + return SetPropertyCallback(name, copy, attributes); } } } @@ -4487,10 +4486,7 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name, } accessors->set(is_getter, fun); - { MaybeObject* maybe_ok = SetPropertyCallback(name, accessors, attributes); - if (maybe_ok->IsFailure()) return maybe_ok; - } - return GetHeap()->undefined_value(); + return SetPropertyCallback(name, accessors, attributes); } @@ -9248,8 +9244,10 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, - bool check_prototype) { + bool check_prototype, + SetPropertyMode set_mode) { Isolate* isolate = GetIsolate(); // Make sure that the top context does not change when doing // callbacks or interceptor calls. @@ -9277,8 +9275,10 @@ MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, MaybeObject* raw_result = this_handle->SetElementWithoutInterceptor(index, *value_handle, + attributes, strict_mode, - check_prototype); + check_prototype, + set_mode); RETURN_IF_SCHEDULED_EXCEPTION(isolate); return raw_result; } @@ -9476,7 +9476,8 @@ MaybeObject* JSObject::SetFastElement(uint32_t index, if (convert_to_slow) { MaybeObject* result = NormalizeElements(); if (result->IsFailure()) return result; - return SetDictionaryElement(index, value, strict_mode, check_prototype); + return SetDictionaryElement(index, value, NONE, strict_mode, + check_prototype); } } // Convert to fast double elements if appropriate. @@ -9526,8 +9527,10 @@ MaybeObject* JSObject::SetFastElement(uint32_t index, MaybeObject* JSObject::SetDictionaryElement(uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, - bool check_prototype) { + bool check_prototype, + SetPropertyMode set_mode) { ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); Isolate* isolate = GetIsolate(); Heap* heap = isolate->heap(); @@ -9547,24 +9550,40 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, if (entry != SeededNumberDictionary::kNotFound) { Object* element = dictionary->ValueAt(entry); PropertyDetails details = dictionary->DetailsAt(entry); - if (details.type() == CALLBACKS) { + if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { return SetElementWithCallback(element, index, value, this, strict_mode); } else { dictionary->UpdateMaxNumberKey(index); // If a value has not been initialized we allow writing to it even if it - // is read-only (a declared const that has not been initialized). - if (!dictionary->DetailsAt(entry).IsReadOnly() || - dictionary->ValueAt(entry)->IsTheHole()) { - dictionary->ValueAtPut(entry, value); - } else if (strict_mode == kStrictMode) { - Handle holder(this); - Handle number = isolate->factory()->NewNumberFromUint(index); - Handle args[2] = { number, holder }; - Handle error = - isolate->factory()->NewTypeError("strict_read_only_property", - HandleVector(args, 2)); - return isolate->Throw(*error); + // is read-only (a declared const that has not been initialized). If a + // value is being defined we skip attribute checks completely. + if (set_mode == DEFINE_PROPERTY) { + details = PropertyDetails(attributes, NORMAL, details.index()); + dictionary->DetailsAtPut(entry, details); + } else if (details.IsReadOnly() && !element->IsTheHole()) { + if (strict_mode == kNonStrictMode) { + return isolate->heap()->undefined_value(); + } else { + Handle holder(this); + Handle number = isolate->factory()->NewNumberFromUint(index); + Handle args[2] = { number, holder }; + Handle error = + isolate->factory()->NewTypeError("strict_read_only_property", + HandleVector(args, 2)); + return isolate->Throw(*error); + } + } + // Elements of the arguments object in slow mode might be slow aliases. + if (is_arguments && element->IsAliasedArgumentsEntry()) { + AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); + Context* context = Context::cast(elements->get(0)); + int context_index = entry->aliased_context_slot(); + ASSERT(!context->get(context_index)->IsTheHole()); + context->set(context_index, value); + // For elements that are still writable we keep slow aliasing. + if (!details.IsReadOnly()) value = element; } + dictionary->ValueAtPut(entry, value); } } else { // Index not already used. Look for an accessor in the prototype chain. @@ -9591,7 +9610,8 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, } } FixedArrayBase* new_dictionary; - MaybeObject* maybe = dictionary->AtNumberPut(index, value); + PropertyDetails details = PropertyDetails(attributes, NORMAL); + MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); if (!maybe->To(&new_dictionary)) return maybe; if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { if (is_arguments) { @@ -9732,18 +9752,22 @@ MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( if (!maybe_obj->ToObject(&obj)) return maybe_obj; } ASSERT(HasDictionaryElements()); - return SetElement(index, value, strict_mode, check_prototype); + return SetElement(index, value, NONE, strict_mode, check_prototype); } MaybeObject* JSReceiver::SetElement(uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, bool check_proto) { - return IsJSProxy() - ? JSProxy::cast(this)->SetElementWithHandler(index, value, strict_mode) - : JSObject::cast(this)->SetElement(index, value, strict_mode, check_proto) - ; + if (IsJSProxy()) { + return JSProxy::cast(this)->SetElementWithHandler( + index, value, strict_mode); + } else { + return JSObject::cast(this)->SetElement( + index, value, attributes, strict_mode, check_proto); + } } @@ -9752,16 +9776,19 @@ Handle JSObject::SetOwnElement(Handle object, Handle value, StrictModeFlag strict_mode) { ASSERT(!object->HasExternalArrayElements()); - CALL_HEAP_FUNCTION(object->GetIsolate(), - object->SetElement(index, *value, strict_mode, false), - Object); + CALL_HEAP_FUNCTION( + object->GetIsolate(), + object->SetElement(index, *value, NONE, strict_mode, false), + Object); } Handle JSObject::SetElement(Handle object, uint32_t index, Handle value, - StrictModeFlag strict_mode) { + PropertyAttributes attr, + StrictModeFlag strict_mode, + SetPropertyMode set_mode) { if (object->HasExternalArrayElements()) { if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) { bool has_exception; @@ -9770,16 +9797,19 @@ Handle JSObject::SetElement(Handle object, value = number; } } - CALL_HEAP_FUNCTION(object->GetIsolate(), - object->SetElement(index, *value, strict_mode, true), - Object); + CALL_HEAP_FUNCTION( + object->GetIsolate(), + object->SetElement(index, *value, attr, strict_mode, true, set_mode), + Object); } MaybeObject* JSObject::SetElement(uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, - bool check_prototype) { + bool check_prototype, + SetPropertyMode set_mode) { // Check access rights if needed. if (IsAccessCheckNeeded()) { Heap* heap = GetHeap(); @@ -9797,29 +9827,59 @@ MaybeObject* JSObject::SetElement(uint32_t index, ASSERT(proto->IsJSGlobalObject()); return JSObject::cast(proto)->SetElement(index, value, + attributes, strict_mode, - check_prototype); + check_prototype, + set_mode); + } + + // Don't allow element properties to be redefined for external arrays. + if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { + Isolate* isolate = GetHeap()->isolate(); + Handle number = isolate->factory()->NewNumberFromUint(index); + Handle args[] = { Handle(this), number }; + Handle error = isolate->factory()->NewTypeError( + "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); + return isolate->Throw(*error); + } + + // Normalize the elements to enable attributes on the property. + if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { + SeededNumberDictionary* dictionary; + MaybeObject* maybe_object = NormalizeElements(); + if (!maybe_object->To(&dictionary)) return maybe_object; + // Make sure that we never go back to fast case. + dictionary->set_requires_slow_elements(); } // Check for lookup interceptor if (HasIndexedInterceptor()) { return SetElementWithInterceptor(index, value, + attributes, strict_mode, - check_prototype); + check_prototype, + set_mode); } return SetElementWithoutInterceptor(index, value, + attributes, strict_mode, - check_prototype); + check_prototype, + set_mode); } MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value, + PropertyAttributes attr, StrictModeFlag strict_mode, - bool check_prototype) { + bool check_prototype, + SetPropertyMode set_mode) { + ASSERT(HasDictionaryElements() || + HasDictionaryArgumentsElements() || + (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); Isolate* isolate = GetIsolate(); switch (GetElementsKind()) { case FAST_SMI_ONLY_ELEMENTS: @@ -9867,7 +9927,8 @@ MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, return array->SetValue(index, value); } case DICTIONARY_ELEMENTS: - return SetDictionaryElement(index, value, strict_mode, check_prototype); + return SetDictionaryElement(index, value, attr, strict_mode, + check_prototype, set_mode); case NON_STRICT_ARGUMENTS_ELEMENTS: { FixedArray* parameter_map = FixedArray::cast(elements()); uint32_t length = parameter_map->length(); @@ -9878,17 +9939,23 @@ MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, int context_index = Smi::cast(probe)->value(); ASSERT(!context->get(context_index)->IsTheHole()); context->set(context_index, value); - return value; - } else { - // Object is not mapped, defer to the arguments. - FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); - if (arguments->IsDictionary()) { - return SetDictionaryElement(index, value, strict_mode, - check_prototype); - } else { - return SetFastElement(index, value, strict_mode, check_prototype); + // Redefining attributes of an aliased element destroys fast aliasing. + if (set_mode == SET_PROPERTY || attr == NONE) return value; + parameter_map->set_the_hole(index + 2); + // For elements that are still writable we re-establish slow aliasing. + if ((attr & READ_ONLY) == 0) { + MaybeObject* maybe_entry = + isolate->heap()->AllocateAliasedArgumentsEntry(context_index); + if (!maybe_entry->ToObject(&value)) return maybe_entry; } } + FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); + if (arguments->IsDictionary()) { + return SetDictionaryElement(index, value, attr, strict_mode, + check_prototype, set_mode); + } else { + return SetFastElement(index, value, strict_mode, check_prototype); + } } } // All possible cases have been handled above. Add a return to avoid the diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index d870ccecb2..be75faba65 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -440,7 +440,8 @@ const int kVariableSizeSentinel = 0; V(SCRIPT, Script, script) \ V(CODE_CACHE, CodeCache, code_cache) \ V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \ - V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) + V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \ + V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) #ifdef ENABLE_DEBUGGER_SUPPORT #define STRUCT_LIST_DEBUGGER(V) \ @@ -596,6 +597,7 @@ enum InstanceType { CODE_CACHE_TYPE, POLYMORPHIC_CODE_CACHE_TYPE, TYPE_FEEDBACK_INFO_TYPE, + ALIASED_ARGUMENTS_ENTRY_TYPE, // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT // is defined. However as include/v8.h contain some of the instance type // constants always having them avoids them getting different numbers @@ -1348,6 +1350,16 @@ enum EnsureElementsMode { }; +// Indicates whether a property should be set or (re)defined. Setting of a +// property causes attributes to remain unchanged, writability to be checked +// and callbacks to be called. Defining of a property causes attributes to +// be updated and callbacks to be overridden. +enum SetPropertyMode { + SET_PROPERTY, + DEFINE_PROPERTY +}; + + // JSReceiver includes types on which properties can be defined, i.e., // JSObject and JSProxy. class JSReceiver: public HeapObject { @@ -1386,6 +1398,7 @@ class JSReceiver: public HeapObject { // Can cause GC, or return failure if GC is required. MUST_USE_RESULT MaybeObject* SetElement(uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, bool check_prototype); @@ -1739,10 +1752,13 @@ class JSObject: public JSReceiver { StrictModeFlag strict_mode, bool check_prototype); - MUST_USE_RESULT MaybeObject* SetDictionaryElement(uint32_t index, - Object* value, - StrictModeFlag strict_mode, - bool check_prototype); + MUST_USE_RESULT MaybeObject* SetDictionaryElement( + uint32_t index, + Object* value, + PropertyAttributes attributes, + StrictModeFlag strict_mode, + bool check_prototype, + SetPropertyMode set_mode = SET_PROPERTY); MUST_USE_RESULT MaybeObject* SetFastDoubleElement( uint32_t index, @@ -1750,23 +1766,28 @@ class JSObject: public JSReceiver { StrictModeFlag strict_mode, bool check_prototype = true); - static Handle SetOwnElement(Handle object, uint32_t index, Handle value, StrictModeFlag strict_mode); // Empty handle is returned if the element cannot be set to the given value. - static MUST_USE_RESULT Handle SetElement(Handle object, - uint32_t index, - Handle value, - StrictModeFlag strict_mode); + static MUST_USE_RESULT Handle SetElement( + Handle object, + uint32_t index, + Handle value, + PropertyAttributes attr, + StrictModeFlag strict_mode, + SetPropertyMode set_mode = SET_PROPERTY); // A Failure object is returned if GC is needed. - MUST_USE_RESULT MaybeObject* SetElement(uint32_t index, - Object* value, - StrictModeFlag strict_mode, - bool check_prototype); + MUST_USE_RESULT MaybeObject* SetElement( + uint32_t index, + Object* value, + PropertyAttributes attributes, + StrictModeFlag strict_mode, + bool check_prototype = true, + SetPropertyMode set_mode = SET_PROPERTY); // Returns the index'th element. // The undefined object if index is out of bounds. @@ -2087,13 +2108,17 @@ class JSObject: public JSReceiver { MUST_USE_RESULT MaybeObject* SetElementWithInterceptor( uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, - bool check_prototype); + bool check_prototype, + SetPropertyMode set_mode); MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor( uint32_t index, Object* value, + PropertyAttributes attributes, StrictModeFlag strict_mode, - bool check_prototype); + bool check_prototype, + SetPropertyMode set_mode); // Searches the prototype chain for a callback setter and sets the property // with the setter if it finds one. The '*found' flag indicates whether @@ -4182,6 +4207,11 @@ class Code: public HeapObject { inline bool is_compiled_optimizable(); inline void set_compiled_optimizable(bool value); + // [has_self_optimization_header]: For FUNCTION kind, tells if it has + // a self-optimization header. + inline bool has_self_optimization_header(); + inline void set_self_optimization_header(bool value); + // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for // how long the function has been marked for OSR and therefore which // level of loop nesting we are willing to do on-stack replacement @@ -4401,6 +4431,7 @@ class Code: public HeapObject { public BitField {}; // NOLINT class FullCodeFlagsHasDebugBreakSlotsField: public BitField {}; class FullCodeFlagsIsCompiledOptimizable: public BitField {}; + class FullCodeFlagsHasSelfOptimizationHeader: public BitField {}; static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1; @@ -6412,6 +6443,39 @@ class TypeFeedbackInfo: public Struct { }; +// Representation of a slow alias as part of a non-strict arguments objects. +// For fast aliases (if HasNonStrictArgumentsElements()): +// - the parameter map contains an index into the context +// - all attributes of the element have default values +// For slow aliases (if HasDictionaryArgumentsElements()): +// - the parameter map contains no fast alias mapping (i.e. the hole) +// - this struct (in the slow backing store) contains an index into the context +// - all attributes are available as part if the property details +class AliasedArgumentsEntry: public Struct { + public: + inline int aliased_context_slot(); + inline void set_aliased_context_slot(int count); + + static inline AliasedArgumentsEntry* cast(Object* obj); + +#ifdef OBJECT_PRINT + inline void AliasedArgumentsEntryPrint() { + AliasedArgumentsEntryPrint(stdout); + } + void AliasedArgumentsEntryPrint(FILE* out); +#endif +#ifdef DEBUG + void AliasedArgumentsEntryVerify(); +#endif + + static const int kAliasedContextSlot = HeapObject::kHeaderSize; + static const int kSize = kAliasedContextSlot + kPointerSize; + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry); +}; + + enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS}; enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL}; diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc index 3dfab294c8..f0556cb355 100644 --- a/deps/v8/src/parser.cc +++ b/deps/v8/src/parser.cc @@ -1188,14 +1188,28 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels, case Token::LET: case Token::CONST: return ParseVariableStatement(kModuleElement, ok); - case Token::MODULE: - return ParseModuleDeclaration(ok); case Token::IMPORT: return ParseImportDeclaration(ok); case Token::EXPORT: return ParseExportDeclaration(ok); - default: - return ParseStatement(labels, ok); + default: { + Statement* stmt = ParseStatement(labels, CHECK_OK); + // Handle 'module' as a context-sensitive keyword. + if (FLAG_harmony_modules && + peek() == Token::IDENTIFIER && + !scanner().HasAnyLineTerminatorBeforeNext() && + stmt != NULL) { + ExpressionStatement* estmt = stmt->AsExpressionStatement(); + if (estmt != NULL && + estmt->expression()->AsVariableProxy() != NULL && + estmt->expression()->AsVariableProxy()->name()->Equals( + isolate()->heap()->module_symbol()) && + !scanner().literal_contains_escapes()) { + return ParseModuleDeclaration(ok); + } + } + return stmt; + } } } @@ -1206,7 +1220,6 @@ Block* Parser::ParseModuleDeclaration(bool* ok) { // Create new block with one expected declaration. Block* block = factory()->NewBlock(NULL, 1, true); - Expect(Token::MODULE, CHECK_OK); Handle name = ParseIdentifier(CHECK_OK); // top_scope_->AddDeclaration( // factory()->NewModuleDeclaration(proxy, module, top_scope_)); @@ -2172,8 +2185,17 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, return ParseNativeDeclaration(ok); } - // Parsed expression statement. - ExpectSemicolon(CHECK_OK); + // Parsed expression statement, or the context-sensitive 'module' keyword. + // Only expect semicolon in the former case. + if (!FLAG_harmony_modules || + peek() != Token::IDENTIFIER || + scanner().HasAnyLineTerminatorBeforeNext() || + expr->AsVariableProxy() == NULL || + !expr->AsVariableProxy()->name()->Equals( + isolate()->heap()->module_symbol()) || + scanner().literal_contains_escapes()) { + ExpectSemicolon(CHECK_OK); + } return factory()->NewExpressionStatement(expr); } diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc index 79134da352..2dc1ed89db 100644 --- a/deps/v8/src/platform-cygwin.cc +++ b/deps/v8/src/platform-cygwin.cc @@ -355,6 +355,17 @@ bool VirtualMemory::Uncommit(void* address, size_t size) { } +bool VirtualMemory::Guard(void* address) { + if (NULL == VirtualAlloc(address, + OS::CommitPageSize(), + MEM_COMMIT, + PAGE_READONLY | PAGE_GUARD)) { + return false; + } + return true; +} + + class Thread::PlatformData : public Malloced { public: PlatformData() : thread_(kNoThread) {} diff --git a/deps/v8/src/platform-freebsd.cc b/deps/v8/src/platform-freebsd.cc index a5981b19c3..f6a426ff44 100644 --- a/deps/v8/src/platform-freebsd.cc +++ b/deps/v8/src/platform-freebsd.cc @@ -411,6 +411,12 @@ bool VirtualMemory::Uncommit(void* address, size_t size) { } +bool VirtualMemory::Guard(void* address) { + OS::Guard(address, OS::CommitPageSize()); + return true; +} + + void* VirtualMemory::ReserveRegion(size_t size) { void* result = mmap(OS::GetRandomMmapAddr(), size, diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc index 14297483c3..0da1c08fdd 100644 --- a/deps/v8/src/platform-linux.cc +++ b/deps/v8/src/platform-linux.cc @@ -666,6 +666,12 @@ bool VirtualMemory::Uncommit(void* address, size_t size) { } +bool VirtualMemory::Guard(void* address) { + OS::Guard(address, OS::CommitPageSize()); + return true; +} + + void* VirtualMemory::ReserveRegion(size_t size) { void* result = mmap(OS::GetRandomMmapAddr(), size, diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc index e367d21a41..89abf398c4 100644 --- a/deps/v8/src/platform-macos.cc +++ b/deps/v8/src/platform-macos.cc @@ -429,6 +429,12 @@ bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { } +bool VirtualMemory::Guard(void* address) { + OS::Guard(address, OS::CommitPageSize()); + return true; +} + + bool VirtualMemory::CommitRegion(void* address, size_t size, bool is_executable) { diff --git a/deps/v8/src/platform-nullos.cc b/deps/v8/src/platform-nullos.cc index 094f950f72..918327a983 100644 --- a/deps/v8/src/platform-nullos.cc +++ b/deps/v8/src/platform-nullos.cc @@ -295,6 +295,12 @@ bool VirtualMemory::Uncommit(void* address, size_t size) { } +bool VirtualMemory::Guard(void* address) { + UNIMPLEMENTED(); + return false; +} + + class Thread::PlatformData : public Malloced { public: PlatformData() { diff --git a/deps/v8/src/platform-openbsd.cc b/deps/v8/src/platform-openbsd.cc index 7e27a01d45..0d6997190c 100644 --- a/deps/v8/src/platform-openbsd.cc +++ b/deps/v8/src/platform-openbsd.cc @@ -458,6 +458,12 @@ bool VirtualMemory::Uncommit(void* address, size_t size) { } +bool VirtualMemory::Guard(void* address) { + OS::Guard(address, OS::CommitPageSize()); + return true; +} + + void* VirtualMemory::ReserveRegion(size_t size) { void* result = mmap(GetRandomMmapAddr(), size, diff --git a/deps/v8/src/platform-solaris.cc b/deps/v8/src/platform-solaris.cc index 349da01edc..004a6ed428 100644 --- a/deps/v8/src/platform-solaris.cc +++ b/deps/v8/src/platform-solaris.cc @@ -401,6 +401,12 @@ bool VirtualMemory::Uncommit(void* address, size_t size) { } +bool VirtualMemory::Guard(void* address) { + OS::Guard(address, OS::CommitPageSize()); + return true; +} + + void* VirtualMemory::ReserveRegion(size_t size) { void* result = mmap(OS::GetRandomMmapAddr(), size, diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc index 6f77b3b797..e9e99246cb 100644 --- a/deps/v8/src/platform-win32.cc +++ b/deps/v8/src/platform-win32.cc @@ -1511,6 +1511,17 @@ bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { } +bool VirtualMemory::Guard(void* address) { + if (NULL == VirtualAlloc(address, + OS::CommitPageSize(), + MEM_COMMIT, + PAGE_READONLY | PAGE_GUARD)) { + return false; + } + return true; +} + + bool VirtualMemory::UncommitRegion(void* base, size_t size) { return VirtualFree(base, size, MEM_DECOMMIT) != 0; } diff --git a/deps/v8/src/platform.h b/deps/v8/src/platform.h index a0186d580f..38e633a380 100644 --- a/deps/v8/src/platform.h +++ b/deps/v8/src/platform.h @@ -356,6 +356,9 @@ class VirtualMemory { // Uncommit real memory. Returns whether the operation succeeded. bool Uncommit(void* address, size_t size); + // Creates a single guard page at the given address. + bool Guard(void* address); + void Release() { ASSERT(IsReserved()); // Notice: Order is important here. The VirtualMemory object might live diff --git a/deps/v8/src/preparser.h b/deps/v8/src/preparser.h index 886d81a9e6..1455561bbd 100644 --- a/deps/v8/src/preparser.h +++ b/deps/v8/src/preparser.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// 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: @@ -28,6 +28,7 @@ #ifndef V8_PREPARSER_H #define V8_PREPARSER_H +#include "hashmap.h" #include "token.h" #include "scanner.h" diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc index 1ba68a1667..156fbc7b63 100644 --- a/deps/v8/src/profile-generator.cc +++ b/deps/v8/src/profile-generator.cc @@ -3166,7 +3166,7 @@ bool HeapSnapshotGenerator::GenerateSnapshot() { debug_heap->Verify(); #endif - SetProgressTotal(4); // 2 passes + dominators + sizes. + SetProgressTotal(2); // 2 passes. #ifdef DEBUG debug_heap->Verify(); @@ -3293,29 +3293,25 @@ bool HeapSnapshotGenerator::BuildDominatorTree( for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; (*dominators)[root_index] = root_index; - // We use time_stamps array to stamp entries with the iteration number - // when the dominance for the entry has been updated. - ScopedVector time_stamps(entries_length); - for (int i = 0; i < entries_length; ++i) time_stamps[i] = -1; + // The affected array is used to mark those entries that may + // be affected because of dominators change among their retainers. + ScopedVector affected(entries_length); + for (int i = 0; i < entries_length; ++i) affected[i] = false; Vector children = entries[root_index]->children(); for (int i = 0; i < children.length(); ++i) { - // Mark the root direct children as affected on iteration zero. - time_stamps[children[i].to()->ordered_index()] = 0; + // Mark the root direct children as affected. + affected[children[i].to()->ordered_index()] = true; } - int changed = 1; - int iteration = 0; - const int base_progress_counter = progress_counter_; - while (changed != 0) { - ++iteration; - changed = 0; + bool changed = true; + while (changed) { + changed = false; for (int i = root_index - 1; i >= 0; --i) { // If dominator of the entry has already been set to root, // then it can't propagate any further. if ((*dominators)[i] == root_index) continue; - // If no retainers of the entry had been updated on current - // or previous iteration, then this entry is not affected. - if (time_stamps[i] < iteration - 1) continue; + if (!affected[i]) continue; + affected[i] = false; int new_idom_index = kNoDominator; Vector rets = entries[i]->retainers(); for (int j = 0; j < rets.length(); ++j) { @@ -3333,17 +3329,13 @@ bool HeapSnapshotGenerator::BuildDominatorTree( if (new_idom_index != kNoDominator && dominators->at(i) != new_idom_index) { (*dominators)[i] = new_idom_index; - ++changed; + changed = true; Vector children = entries[i]->children(); for (int j = 0; j < children.length(); ++j) { - time_stamps[children[j].to()->ordered_index()] = iteration; + affected[children[j].to()->ordered_index()] = true; } } } - int remaining = entries_length - changed; - ASSERT(remaining >= 0); - progress_counter_ = base_progress_counter + remaining; - if (!ProgressReport(true)) return false; } return true; } @@ -3367,21 +3359,19 @@ bool HeapSnapshotGenerator::ApproximateRetainedSizes() { // As for the dominators tree we only know parent nodes, not // children, to sum up total sizes we "bubble" node's self size // adding it to all of its parents. - for (int i = 0; i < snapshot_->entries()->length(); ++i) { - HeapEntry* entry = snapshot_->entries()->at(i); + List& entries = *snapshot_->entries(); + for (int i = 0; i < entries.length(); ++i) { + HeapEntry* entry = entries[i]; entry->set_retained_size(entry->self_size()); } - for (int i = 0; - i < snapshot_->entries()->length(); - ++i, ProgressStep()) { - HeapEntry* entry = snapshot_->entries()->at(i); + for (int i = 0; i < entries.length(); ++i) { + HeapEntry* entry = entries[i]; int entry_size = entry->self_size(); for (HeapEntry* dominator = entry->dominator(); dominator != entry; entry = dominator, dominator = entry->dominator()) { dominator->add_retained_size(entry_size); } - if (!ProgressReport()) return false; } return true; } diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc index 9597681959..b377e6e54b 100644 --- a/deps/v8/src/runtime.cc +++ b/deps/v8/src/runtime.cc @@ -1039,7 +1039,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { elms->set(IS_ACCESSOR_INDEX, heap->false_value()); elms->set(VALUE_INDEX, *substr); elms->set(WRITABLE_INDEX, heap->false_value()); - elms->set(ENUMERABLE_INDEX, heap->false_value()); + elms->set(ENUMERABLE_INDEX, heap->true_value()); elms->set(CONFIGURABLE_INDEX, heap->false_value()); return *desc; } @@ -4355,53 +4355,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); PropertyAttributes attr = static_cast(unchecked); - // Check if this is an element. - uint32_t index; - bool is_element = name->AsArrayIndex(&index); - - // Special case for elements if any of the flags might be involved. - // If elements are in fast case we always implicitly assume that: - // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. - if (is_element && (attr != NONE || - js_object->HasLocalElement(index) == JSObject::DICTIONARY_ELEMENT)) { - // Normalize the elements to enable attributes on the property. - if (js_object->IsJSGlobalProxy()) { - // We do not need to do access checks here since these has already - // been performed by the call to GetOwnProperty. - Handle proto(js_object->GetPrototype()); - // If proxy is detached, ignore the assignment. Alternatively, - // we could throw an exception. - if (proto->IsNull()) return *obj_value; - js_object = Handle::cast(proto); - } - - // Don't allow element properties to be redefined on objects with external - // array elements. - if (js_object->HasExternalArrayElements()) { - Handle args[2] = { js_object, name }; - Handle error = - isolate->factory()->NewTypeError("redef_external_array_element", - HandleVector(args, 2)); - return isolate->Throw(*error); - } - - Handle dictionary = - JSObject::NormalizeElements(js_object); - // Make sure that we never go back to fast case. - dictionary->set_requires_slow_elements(); - PropertyDetails details = PropertyDetails(attr, NORMAL); - Handle extended_dictionary = - SeededNumberDictionary::Set(dictionary, index, obj_value, details); - if (*extended_dictionary != *dictionary) { - if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { - FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); - } else { - js_object->set_elements(*extended_dictionary); - } - } - return *obj_value; - } - LookupResult result(isolate); js_object->LocalLookupRealNamedProperty(*name, &result); @@ -4457,35 +4410,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { } -// Special case for elements if any of the flags are true. -// If elements are in fast case we always implicitly assume that: -// DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. -static MaybeObject* NormalizeObjectSetElement(Isolate* isolate, - Handle js_object, - uint32_t index, - Handle value, - PropertyAttributes attr) { - // Normalize the elements to enable attributes on the property. - Handle dictionary = - JSObject::NormalizeElements(js_object); - // Make sure that we never go back to fast case. - dictionary->set_requires_slow_elements(); - PropertyDetails details = PropertyDetails(attr, NORMAL); - Handle extended_dictionary = - SeededNumberDictionary::Set(dictionary, index, value, details); - if (*extended_dictionary != *dictionary) { - js_object->set_elements(*extended_dictionary); - } - return *value; -} - - MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, Handle object, Handle key, Handle value, PropertyAttributes attr, StrictModeFlag strict_mode) { + SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY; HandleScope scope(isolate); if (object->IsUndefined() || object->IsNull()) { @@ -4523,12 +4454,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, return *value; } - if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { - return NormalizeObjectSetElement(isolate, js_object, index, value, attr); - } - - Handle result = - JSObject::SetElement(js_object, index, value, strict_mode); + Handle result = JSObject::SetElement( + js_object, index, value, attr, strict_mode, set_mode); if (result.is_null()) return Failure::Exception(); return *value; } @@ -4536,15 +4463,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, if (key->IsString()) { Handle result; if (Handle::cast(key)->AsArrayIndex(&index)) { - if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { - return NormalizeObjectSetElement(isolate, - js_object, - index, - value, - attr); - } - result = - JSObject::SetElement(js_object, index, value, strict_mode); + result = JSObject::SetElement( + js_object, index, value, attr, strict_mode, set_mode); } else { Handle key_string = Handle::cast(key); key_string->TryFlatten(); @@ -4562,7 +4482,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, Handle name = Handle::cast(converted); if (name->AsArrayIndex(&index)) { - return js_object->SetElement(index, *value, strict_mode, true); + return js_object->SetElement( + index, *value, attr, strict_mode, true, set_mode); } else { return js_object->SetProperty(*name, *value, attr, strict_mode); } @@ -4590,12 +4511,14 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, return *value; } - return js_object->SetElement(index, *value, kNonStrictMode, true); + return js_object->SetElement( + index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); } if (key->IsString()) { if (Handle::cast(key)->AsArrayIndex(&index)) { - return js_object->SetElement(index, *value, kNonStrictMode, true); + return js_object->SetElement( + index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); } else { Handle key_string = Handle::cast(key); key_string->TryFlatten(); @@ -4612,7 +4535,8 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, Handle name = Handle::cast(converted); if (name->AsArrayIndex(&index)) { - return js_object->SetElement(index, *value, kNonStrictMode, true); + return js_object->SetElement( + index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); } else { return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); } @@ -10316,9 +10240,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) { RETURN_IF_EMPTY_HANDLE(isolate, tmp2); RETURN_IF_EMPTY_HANDLE( - isolate, JSObject::SetElement(jsobject, index1, tmp2, kStrictMode)); + isolate, JSObject::SetElement(jsobject, index1, tmp2, NONE, kStrictMode)); RETURN_IF_EMPTY_HANDLE( - isolate, JSObject::SetElement(jsobject, index2, tmp1, kStrictMode)); + isolate, JSObject::SetElement(jsobject, index2, tmp1, NONE, kStrictMode)); return isolate->heap()->undefined_value(); } diff --git a/deps/v8/src/scanner.cc b/deps/v8/src/scanner.cc index 42a1c2bc31..72768b381b 100755 --- a/deps/v8/src/scanner.cc +++ b/deps/v8/src/scanner.cc @@ -850,9 +850,6 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() { KEYWORD_GROUP('l') \ KEYWORD("let", harmony_scoping \ ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \ - KEYWORD_GROUP('m') \ - KEYWORD("module", harmony_modules \ - ? Token::MODULE : Token::IDENTIFIER) \ KEYWORD_GROUP('n') \ KEYWORD("new", Token::NEW) \ KEYWORD("null", Token::NULL_LITERAL) \ diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc index 9835108751..8d71f8ae85 100644 --- a/deps/v8/src/scopes.cc +++ b/deps/v8/src/scopes.cc @@ -39,26 +39,6 @@ namespace v8 { namespace internal { -// ---------------------------------------------------------------------------- -// A Zone allocator for use with LocalsMap. - -// TODO(isolates): It is probably worth it to change the Allocator class to -// take a pointer to an isolate. -class ZoneAllocator: public Allocator { - public: - /* nothing to do */ - virtual ~ZoneAllocator() {} - - virtual void* New(size_t size) { return ZONE->New(static_cast(size)); } - - /* ignored - Zone is freed in one fell swoop */ - virtual void Delete(void* p) {} -}; - - -static ZoneAllocator* LocalsMapAllocator = ::new ZoneAllocator(); - - // ---------------------------------------------------------------------------- // Implementation of LocalsMap // @@ -77,7 +57,7 @@ static bool Match(void* key1, void* key2) { } -VariableMap::VariableMap() : HashMap(Match, LocalsMapAllocator, 8) {} +VariableMap::VariableMap() : ZoneHashMap(Match, 8) {} VariableMap::~VariableMap() {} @@ -88,7 +68,7 @@ Variable* VariableMap::Declare( bool is_valid_lhs, Variable::Kind kind, InitializationFlag initialization_flag) { - HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); + Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true); if (p->value == NULL) { // The variable has not been declared yet -> insert it. ASSERT(p->key == name.location()); @@ -104,7 +84,7 @@ Variable* VariableMap::Declare( Variable* VariableMap::Lookup(Handle name) { - HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); + Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false); if (p != NULL) { ASSERT(*reinterpret_cast(p->key) == *name); ASSERT(p->value != NULL); diff --git a/deps/v8/src/scopes.h b/deps/v8/src/scopes.h index 5b645f29c2..30c95ee4e5 100644 --- a/deps/v8/src/scopes.h +++ b/deps/v8/src/scopes.h @@ -29,7 +29,7 @@ #define V8_SCOPES_H_ #include "ast.h" -#include "hashmap.h" +#include "zone.h" namespace v8 { namespace internal { @@ -38,7 +38,7 @@ class CompilationInfo; // A hash map to support fast variable declaration and lookup. -class VariableMap: public HashMap { +class VariableMap: public ZoneHashMap { public: VariableMap(); diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc index d9fc2b7b7c..81a94ddc8a 100644 --- a/deps/v8/src/serialize.cc +++ b/deps/v8/src/serialize.cc @@ -1088,9 +1088,10 @@ Serializer::Serializer(SnapshotByteSink* sink) external_reference_encoder_(new ExternalReferenceEncoder), large_object_total_(0), root_index_wave_front_(0) { + isolate_ = Isolate::Current(); // The serializer is meant to be used only to generate initial heap images // from a context in which there is only one isolate. - ASSERT(Isolate::Current()->IsDefaultIsolate()); + ASSERT(isolate_->IsDefaultIsolate()); for (int i = 0; i <= LAST_SPACE; i++) { fullness_[i] = 0; } @@ -1642,8 +1643,8 @@ int Serializer::Allocate(int space, int size, bool* new_page) { // serialized address. CHECK(IsPowerOf2(Page::kPageSize)); int used_in_this_page = (fullness_[space] & (Page::kPageSize - 1)); - CHECK(size <= Page::kObjectAreaSize); - if (used_in_this_page + size > Page::kObjectAreaSize) { + CHECK(size <= SpaceAreaSize(space)); + if (used_in_this_page + size > SpaceAreaSize(space)) { *new_page = true; fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); } @@ -1654,4 +1655,13 @@ int Serializer::Allocate(int space, int size, bool* new_page) { } +int Serializer::SpaceAreaSize(int space) { + if (space == CODE_SPACE) { + return isolate_->memory_allocator()->CodePageAreaSize(); + } else { + return Page::kPageSize - Page::kObjectStartOffset; + } +} + + } } // namespace v8::internal diff --git a/deps/v8/src/serialize.h b/deps/v8/src/serialize.h index 72eed5ad2f..02bf58a9ee 100644 --- a/deps/v8/src/serialize.h +++ b/deps/v8/src/serialize.h @@ -556,6 +556,9 @@ class Serializer : public SerializerDeserializer { return external_reference_encoder_->Encode(addr); } + int SpaceAreaSize(int space); + + Isolate* isolate_; // Keep track of the fullness of each space in order to generate // relative addresses for back references. Large objects are // just numbered sequentially since relative addresses make no diff --git a/deps/v8/src/spaces-inl.h b/deps/v8/src/spaces-inl.h index d0cddebf78..3709009c9b 100644 --- a/deps/v8/src/spaces-inl.h +++ b/deps/v8/src/spaces-inl.h @@ -166,10 +166,8 @@ Page* Page::Initialize(Heap* heap, Page* page = reinterpret_cast(chunk); ASSERT(chunk->size() == static_cast(kPageSize)); ASSERT(chunk->owner() == owner); - owner->IncreaseCapacity(Page::kObjectAreaSize); - owner->Free(page->ObjectAreaStart(), - static_cast(page->ObjectAreaEnd() - - page->ObjectAreaStart())); + owner->IncreaseCapacity(page->area_size()); + owner->Free(page->area_start(), page->area_size()); heap->incremental_marking()->SetOldSpacePageFlags(chunk); diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc index 05c5876fdf..1fbad551af 100644 --- a/deps/v8/src/spaces.cc +++ b/deps/v8/src/spaces.cc @@ -75,8 +75,8 @@ HeapObjectIterator::HeapObjectIterator(Page* page, owner == HEAP->cell_space() || owner == HEAP->code_space()); Initialize(reinterpret_cast(owner), - page->ObjectAreaStart(), - page->ObjectAreaEnd(), + page->area_start(), + page->area_end(), kOnePageOnly, size_func); ASSERT(page->WasSweptPrecisely()); @@ -108,12 +108,12 @@ bool HeapObjectIterator::AdvanceToNextPage() { cur_page = space_->anchor(); } else { cur_page = Page::FromAddress(cur_addr_ - 1); - ASSERT(cur_addr_ == cur_page->ObjectAreaEnd()); + ASSERT(cur_addr_ == cur_page->area_end()); } cur_page = cur_page->next_page(); if (cur_page == space_->anchor()) return false; - cur_addr_ = cur_page->ObjectAreaStart(); - cur_end_ = cur_page->ObjectAreaEnd(); + cur_addr_ = cur_page->area_start(); + cur_end_ = cur_page->area_end(); ASSERT(cur_page->WasSweptPrecisely()); return true; } @@ -227,7 +227,9 @@ Address CodeRange::AllocateRawMemory(const size_t requested, } ASSERT(*allocated <= current.size); ASSERT(IsAddressAligned(current.start, MemoryChunk::kAlignment)); - if (!code_range_->Commit(current.start, *allocated, true)) { + if (!MemoryAllocator::CommitCodePage(code_range_, + current.start, + *allocated)) { *allocated = 0; return NULL; } @@ -358,11 +360,17 @@ Address MemoryAllocator::AllocateAlignedMemory(size_t size, VirtualMemory reservation; Address base = ReserveAlignedMemory(size, alignment, &reservation); if (base == NULL) return NULL; - if (!reservation.Commit(base, - size, - executable == EXECUTABLE)) { - return NULL; + + if (executable == EXECUTABLE) { + CommitCodePage(&reservation, base, size); + } else { + if (!reservation.Commit(base, + size, + executable == EXECUTABLE)) { + return NULL; + } } + controller->TakeControl(&reservation); return base; } @@ -378,9 +386,14 @@ void Page::InitializeAsAnchor(PagedSpace* owner) { NewSpacePage* NewSpacePage::Initialize(Heap* heap, Address start, SemiSpace* semi_space) { + Address area_start = start + NewSpacePage::kObjectStartOffset; + Address area_end = start + Page::kPageSize; + MemoryChunk* chunk = MemoryChunk::Initialize(heap, start, Page::kPageSize, + area_start, + area_end, NOT_EXECUTABLE, semi_space); chunk->set_next_chunk(NULL); @@ -410,6 +423,8 @@ void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, + Address area_start, + Address area_end, Executability executable, Space* owner) { MemoryChunk* chunk = FromAddress(base); @@ -418,6 +433,8 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, chunk->heap_ = heap; chunk->size_ = size; + chunk->area_start_ = area_start; + chunk->area_end_ = area_end; chunk->flags_ = 0; chunk->set_owner(owner); chunk->InitializeReservedMemory(); @@ -431,9 +448,13 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); ASSERT(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); - if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE); + if (executable == EXECUTABLE) { + chunk->SetFlag(IS_EXECUTABLE); + } - if (owner == heap->old_data_space()) chunk->SetFlag(CONTAINS_ONLY_DATA); + if (owner == heap->old_data_space()) { + chunk->SetFlag(CONTAINS_ONLY_DATA); + } return chunk; } @@ -462,11 +483,16 @@ void MemoryChunk::Unlink() { MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, Executability executable, Space* owner) { - size_t chunk_size = MemoryChunk::kObjectStartOffset + body_size; + size_t chunk_size; Heap* heap = isolate_->heap(); Address base = NULL; VirtualMemory reservation; + Address area_start = NULL; + Address area_end = NULL; if (executable == EXECUTABLE) { + chunk_size = RoundUp(CodePageAreaStartOffset() + body_size, + OS::CommitPageSize()) + CodePageGuardSize(); + // Check executable memory limit. if (size_executable_ + chunk_size > capacity_executable_) { LOG(isolate_, @@ -494,18 +520,30 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, // Update executable memory size. size_executable_ += reservation.size(); } + +#ifdef DEBUG + ZapBlock(base, CodePageGuardStartOffset()); + ZapBlock(base + CodePageAreaStartOffset(), body_size); +#endif + area_start = base + CodePageAreaStartOffset(); + area_end = area_start + body_size; } else { + chunk_size = MemoryChunk::kObjectStartOffset + body_size; base = AllocateAlignedMemory(chunk_size, MemoryChunk::kAlignment, executable, &reservation); if (base == NULL) return NULL; - } #ifdef DEBUG - ZapBlock(base, chunk_size); + ZapBlock(base, chunk_size); #endif + + area_start = base + Page::kObjectStartOffset; + area_end = base + chunk_size; + } + isolate_->counters()->memory_allocated()-> Increment(static_cast(chunk_size)); @@ -518,6 +556,8 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, MemoryChunk* result = MemoryChunk::Initialize(heap, base, chunk_size, + area_start, + area_end, executable, owner); result->set_reserved_memory(&reservation); @@ -527,7 +567,9 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, Page* MemoryAllocator::AllocatePage(PagedSpace* owner, Executability executable) { - MemoryChunk* chunk = AllocateChunk(Page::kObjectAreaSize, executable, owner); + MemoryChunk* chunk = AllocateChunk(owner->AreaSize(), + executable, + owner); if (chunk == NULL) return NULL; @@ -648,6 +690,65 @@ void MemoryAllocator::ReportStatistics() { } #endif + +int MemoryAllocator::CodePageGuardStartOffset() { + // We are guarding code pages: the first OS page after the header + // will be protected as non-writable. + return RoundUp(Page::kObjectStartOffset, OS::CommitPageSize()); +} + + +int MemoryAllocator::CodePageGuardSize() { + return static_cast(OS::CommitPageSize()); +} + + +int MemoryAllocator::CodePageAreaStartOffset() { + // We are guarding code pages: the first OS page after the header + // will be protected as non-writable. + return CodePageGuardStartOffset() + CodePageGuardSize(); +} + + +int MemoryAllocator::CodePageAreaEndOffset() { + // We are guarding code pages: the last OS page will be protected as + // non-writable. + return Page::kPageSize - static_cast(OS::CommitPageSize()); +} + + +bool MemoryAllocator::CommitCodePage(VirtualMemory* vm, + Address start, + size_t size) { + // Commit page header (not executable). + if (!vm->Commit(start, + CodePageGuardStartOffset(), + false)) { + return false; + } + + // Create guard page after the header. + if (!vm->Guard(start + CodePageGuardStartOffset())) { + return false; + } + + // Commit page body (executable). + size_t area_size = size - CodePageAreaStartOffset() - CodePageGuardSize(); + if (!vm->Commit(start + CodePageAreaStartOffset(), + area_size, + true)) { + return false; + } + + // Create guard page after the allocatable area. + if (!vm->Guard(start + CodePageAreaStartOffset() + area_size)) { + return false; + } + + return true; +} + + // ----------------------------------------------------------------------------- // MemoryChunk implementation @@ -671,8 +772,14 @@ PagedSpace::PagedSpace(Heap* heap, was_swept_conservatively_(false), first_unswept_page_(Page::FromAddress(NULL)), unswept_free_bytes_(0) { + if (id == CODE_SPACE) { + area_size_ = heap->isolate()->memory_allocator()-> + CodePageAreaSize(); + } else { + area_size_ = Page::kPageSize - Page::kObjectStartOffset; + } max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize) - * Page::kObjectAreaSize; + * AreaSize(); accounting_stats_.Clear(); allocation_info_.top = NULL; @@ -722,8 +829,8 @@ MaybeObject* PagedSpace::FindObject(Address addr) { } bool PagedSpace::CanExpand() { - ASSERT(max_capacity_ % Page::kObjectAreaSize == 0); - ASSERT(Capacity() % Page::kObjectAreaSize == 0); + ASSERT(max_capacity_ % AreaSize() == 0); + ASSERT(Capacity() % AreaSize() == 0); if (Capacity() == max_capacity_) return false; @@ -763,6 +870,7 @@ int PagedSpace::CountTotalPages() { void PagedSpace::ReleasePage(Page* page) { ASSERT(page->LiveBytes() == 0); + ASSERT(AreaSize() == page->area_size()); // Adjust list of unswept pages if the page is the head of the list. if (first_unswept_page_ == page) { @@ -775,7 +883,7 @@ void PagedSpace::ReleasePage(Page* page) { if (page->WasSwept()) { intptr_t size = free_list_.EvictFreeListItems(page); accounting_stats_.AllocateBytes(size); - ASSERT_EQ(Page::kObjectAreaSize, static_cast(size)); + ASSERT_EQ(AreaSize(), static_cast(size)); } else { DecreaseUnsweptFreeBytes(page); } @@ -792,8 +900,8 @@ void PagedSpace::ReleasePage(Page* page) { } ASSERT(Capacity() > 0); - ASSERT(Capacity() % Page::kObjectAreaSize == 0); - accounting_stats_.ShrinkSpace(Page::kObjectAreaSize); + ASSERT(Capacity() % AreaSize() == 0); + accounting_stats_.ShrinkSpace(AreaSize()); } @@ -804,9 +912,9 @@ void PagedSpace::ReleaseAllUnusedPages() { if (!page->WasSwept()) { if (page->LiveBytes() == 0) ReleasePage(page); } else { - HeapObject* obj = HeapObject::FromAddress(page->body()); + HeapObject* obj = HeapObject::FromAddress(page->area_start()); if (obj->IsFreeSpace() && - FreeSpace::cast(obj)->size() == Page::kObjectAreaSize) { + FreeSpace::cast(obj)->size() == AreaSize()) { // Sometimes we allocate memory from free list but don't // immediately initialize it (e.g. see PagedSpace::ReserveSpace // called from Heap::ReserveSpace that can cause GC before @@ -817,7 +925,7 @@ void PagedSpace::ReleaseAllUnusedPages() { // by free list items. FreeList::SizeStats sizes; free_list_.CountFreeListItems(page, &sizes); - if (sizes.Total() == Page::kObjectAreaSize) { + if (sizes.Total() == AreaSize()) { ReleasePage(page); } } @@ -848,8 +956,8 @@ void PagedSpace::Verify(ObjectVisitor* visitor) { } ASSERT(page->WasSweptPrecisely()); HeapObjectIterator it(page, NULL); - Address end_of_previous_object = page->ObjectAreaStart(); - Address top = page->ObjectAreaEnd(); + Address end_of_previous_object = page->area_start(); + Address top = page->area_end(); int black_size = 0; for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { ASSERT(end_of_previous_object <= object->address()); @@ -1061,7 +1169,7 @@ bool NewSpace::AddFreshPage() { } // Clear remainder of current page. - Address limit = NewSpacePage::FromLimit(top)->body_limit(); + Address limit = NewSpacePage::FromLimit(top)->area_end(); if (heap()->gc_state() == Heap::SCAVENGE) { heap()->promotion_queue()->SetNewLimit(limit); heap()->promotion_queue()->ActivateGuardIfOnTheSamePage(); @@ -1111,7 +1219,7 @@ void NewSpace::Verify() { // There should be objects packed in from the low address up to the // allocation pointer. - Address current = to_space_.first_page()->body(); + Address current = to_space_.first_page()->area_start(); CHECK_EQ(current, to_space_.space_start()); while (current != top()) { @@ -1146,7 +1254,7 @@ void NewSpace::Verify() { NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page(); // Next page should be valid. CHECK(!page->is_anchor()); - current = page->body(); + current = page->area_start(); } } @@ -1932,7 +2040,7 @@ static intptr_t CountFreeListItemsInList(FreeListNode* n, Page* p) { void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) { sizes->huge_size_ = CountFreeListItemsInList(huge_list_, p); - if (sizes->huge_size_ < Page::kObjectAreaSize) { + if (sizes->huge_size_ < p->area_size()) { sizes->small_size_ = CountFreeListItemsInList(small_list_, p); sizes->medium_size_ = CountFreeListItemsInList(medium_list_, p); sizes->large_size_ = CountFreeListItemsInList(large_list_, p); @@ -1962,7 +2070,7 @@ static intptr_t EvictFreeListItemsInList(FreeListNode** n, Page* p) { intptr_t FreeList::EvictFreeListItems(Page* p) { intptr_t sum = EvictFreeListItemsInList(&huge_list_, p); - if (sum < Page::kObjectAreaSize) { + if (sum < p->area_size()) { sum += EvictFreeListItemsInList(&small_list_, p) + EvictFreeListItemsInList(&medium_list_, p) + EvictFreeListItemsInList(&large_list_, p); @@ -2084,7 +2192,7 @@ void PagedSpace::PrepareForMarkCompact() { bool PagedSpace::ReserveSpace(int size_in_bytes) { - ASSERT(size_in_bytes <= Page::kMaxHeapObjectSize); + ASSERT(size_in_bytes <= AreaSize()); ASSERT(size_in_bytes == RoundSizeDownToObjectAlignment(size_in_bytes)); Address current_top = allocation_info_.top; Address new_top = current_top + size_in_bytes; @@ -2464,7 +2572,7 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size, LargePage* page = heap()->isolate()->memory_allocator()-> AllocateLargePage(object_size, executable, this); if (page == NULL) return Failure::RetryAfterGC(identity()); - ASSERT(page->body_size() >= object_size); + ASSERT(page->area_size() >= object_size); size_ += static_cast(page->size()); objects_size_ += object_size; @@ -2580,7 +2688,7 @@ void LargeObjectSpace::Verify() { // object area start. HeapObject* object = chunk->GetObject(); Page* page = Page::FromAddress(object->address()); - ASSERT(object->address() == page->ObjectAreaStart()); + ASSERT(object->address() == page->area_start()); // The first word should be a map, and we expect all map pointers to be // in map space. diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h index 0ff62b58e4..599e9dd6fa 100644 --- a/deps/v8/src/spaces.h +++ b/deps/v8/src/spaces.h @@ -103,7 +103,7 @@ class Isolate; ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0) #define ASSERT_OBJECT_SIZE(size) \ - ASSERT((0 < size) && (size <= Page::kMaxHeapObjectSize)) + ASSERT((0 < size) && (size <= Page::kMaxNonCodeHeapObjectSize)) #define ASSERT_PAGE_OFFSET(offset) \ ASSERT((Page::kObjectStartOffset <= offset) \ @@ -361,21 +361,15 @@ class MemoryChunk { store_buffer_counter_ = counter; } - Address body() { return address() + kObjectStartOffset; } - - Address body_limit() { return address() + size(); } - - int body_size() { return static_cast(size() - kObjectStartOffset); } - bool Contains(Address addr) { - return addr >= body() && addr < address() + size(); + return addr >= area_start() && addr < area_end(); } // Checks whether addr can be a limit of addresses in this page. // It's a limit if it's in the page, or if it's just after the // last byte of the page. bool ContainsLimit(Address addr) { - return addr >= body() && addr <= address() + size(); + return addr >= area_start() && addr <= area_end(); } enum MemoryChunkFlags { @@ -487,8 +481,9 @@ class MemoryChunk { static const intptr_t kSizeOffset = kPointerSize + kPointerSize; static const intptr_t kLiveBytesOffset = - kSizeOffset + kPointerSize + kPointerSize + kPointerSize + - kPointerSize + kPointerSize + kPointerSize + kIntSize; + kSizeOffset + kPointerSize + kPointerSize + kPointerSize + + kPointerSize + kPointerSize + + kPointerSize + kPointerSize + kPointerSize + kIntSize; static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; @@ -594,12 +589,22 @@ class MemoryChunk { ClearFlag(EVACUATION_CANDIDATE); } + Address area_start() { return area_start_; } + Address area_end() { return area_end_; } + int area_size() { + return static_cast(area_end() - area_start()); + } protected: MemoryChunk* next_chunk_; MemoryChunk* prev_chunk_; size_t size_; intptr_t flags_; + + // Start and end of allocatable memory on this chunk. + Address area_start_; + Address area_end_; + // If the chunk needs to remember its memory reservation, it is stored here. VirtualMemory reservation_; // The identity of the owning space. This is tagged as a failure pointer, but @@ -618,6 +623,8 @@ class MemoryChunk { static MemoryChunk* Initialize(Heap* heap, Address base, size_t size, + Address area_start, + Address area_end, Executability executable, Space* owner); @@ -657,12 +664,6 @@ class Page : public MemoryChunk { inline void set_next_page(Page* page); inline void set_prev_page(Page* page); - // Returns the start address of the object area in this page. - Address ObjectAreaStart() { return address() + kObjectStartOffset; } - - // Returns the end address (exclusive) of the object area in this page. - Address ObjectAreaEnd() { return address() + Page::kPageSize; } - // Checks whether an address is page aligned. static bool IsAlignedToPageSize(Address a) { return 0 == (OffsetFrom(a) & kPageAlignmentMask); @@ -685,21 +686,14 @@ class Page : public MemoryChunk { // Page size in bytes. This must be a multiple of the OS page size. static const int kPageSize = 1 << kPageSizeBits; - // Page size mask. - static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; - // Object area size in bytes. - static const int kObjectAreaSize = kPageSize - kObjectStartOffset; + static const int kNonCodeObjectAreaSize = kPageSize - kObjectStartOffset; // Maximum object size that fits in a page. - static const int kMaxHeapObjectSize = kObjectAreaSize; - - static const int kFirstUsedCell = - (kObjectStartOffset/kPointerSize) >> Bitmap::kBitsPerCellLog2; + static const int kMaxNonCodeHeapObjectSize = kNonCodeObjectAreaSize; - static const int kLastUsedCell = - ((kPageSize - kPointerSize)/kPointerSize) >> - Bitmap::kBitsPerCellLog2; + // Page size mask. + static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; inline void ClearGCFields(); @@ -734,7 +728,7 @@ STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); class LargePage : public MemoryChunk { public: HeapObject* GetObject() { - return HeapObject::FromAddress(body()); + return HeapObject::FromAddress(area_start()); } inline LargePage* next_page() const { @@ -975,7 +969,7 @@ class MemoryAllocator { // Returns maximum available bytes that the old space can have. intptr_t MaxAvailable() { - return (Available() / Page::kPageSize) * Page::kObjectAreaSize; + return (Available() / Page::kPageSize) * Page::kMaxNonCodeHeapObjectSize; } #ifdef DEBUG @@ -1028,6 +1022,20 @@ class MemoryAllocator { bool MemoryAllocationCallbackRegistered( MemoryAllocationCallback callback); + static int CodePageGuardStartOffset(); + + static int CodePageGuardSize(); + + static int CodePageAreaStartOffset(); + + static int CodePageAreaEndOffset(); + + static int CodePageAreaSize() { + return CodePageAreaEndOffset() - CodePageAreaStartOffset(); + } + + static bool CommitCodePage(VirtualMemory* vm, Address start, size_t size); + private: Isolate* isolate_; @@ -1380,7 +1388,7 @@ class FreeList BASE_EMBEDDED { private: // The size range of blocks, in bytes. static const int kMinBlockSize = 3 * kPointerSize; - static const int kMaxBlockSize = Page::kMaxHeapObjectSize; + static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); @@ -1572,12 +1580,12 @@ class PagedSpace : public Space { void IncreaseUnsweptFreeBytes(Page* p) { ASSERT(ShouldBeSweptLazily(p)); - unswept_free_bytes_ += (Page::kObjectAreaSize - p->LiveBytes()); + unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); } void DecreaseUnsweptFreeBytes(Page* p) { ASSERT(ShouldBeSweptLazily(p)); - unswept_free_bytes_ -= (Page::kObjectAreaSize - p->LiveBytes()); + unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); } bool AdvanceSweeper(intptr_t bytes_to_sweep); @@ -1600,7 +1608,14 @@ class PagedSpace : public Space { // Returns the number of total pages in this space. int CountTotalPages(); + // Return size of allocatable area on a page in this space. + inline int AreaSize() { + return area_size_; + } + protected: + int area_size_; + // Maximum capacity of this space. intptr_t max_capacity_; @@ -1702,6 +1717,8 @@ class NewSpacePage : public MemoryChunk { (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) | (1 << MemoryChunk::SCAN_ON_SCAVENGE); + static const int kAreaSize = Page::kNonCodeObjectAreaSize; + inline NewSpacePage* next_page() const { return static_cast(next_chunk()); } @@ -1814,22 +1831,22 @@ class SemiSpace : public Space { // Returns the start address of the first page of the space. Address space_start() { ASSERT(anchor_.next_page() != &anchor_); - return anchor_.next_page()->body(); + return anchor_.next_page()->area_start(); } // Returns the start address of the current page of the space. Address page_low() { - return current_page_->body(); + return current_page_->area_start(); } // Returns one past the end address of the space. Address space_end() { - return anchor_.prev_page()->body_limit(); + return anchor_.prev_page()->area_end(); } // Returns one past the end address of the current page of the space. Address page_high() { - return current_page_->body_limit(); + return current_page_->area_end(); } bool AdvancePage() { @@ -1965,7 +1982,7 @@ class SemiSpaceIterator : public ObjectIterator { NewSpacePage* page = NewSpacePage::FromLimit(current_); page = page->next_page(); ASSERT(!page->is_anchor()); - current_ = page->body(); + current_ = page->area_start(); if (current_ == limit_) return NULL; } @@ -2073,7 +2090,7 @@ class NewSpace : public Space { // Return the allocated bytes in the active semispace. virtual intptr_t Size() { - return pages_used_ * Page::kObjectAreaSize + + return pages_used_ * NewSpacePage::kAreaSize + static_cast(top() - to_space_.page_low()); } @@ -2085,7 +2102,7 @@ class NewSpace : public Space { // Return the current capacity of a semispace. intptr_t EffectiveCapacity() { SLOW_ASSERT(to_space_.Capacity() == from_space_.Capacity()); - return (to_space_.Capacity() / Page::kPageSize) * Page::kObjectAreaSize; + return (to_space_.Capacity() / Page::kPageSize) * NewSpacePage::kAreaSize; } // Return the current capacity of a semispace. @@ -2302,7 +2319,7 @@ class OldSpace : public PagedSpace { // The limit of allocation for a page in this space. virtual Address PageAllocationLimit(Page* page) { - return page->ObjectAreaEnd(); + return page->area_end(); } public: @@ -2331,12 +2348,12 @@ class FixedSpace : public PagedSpace { : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), object_size_in_bytes_(object_size_in_bytes), name_(name) { - page_extra_ = Page::kObjectAreaSize % object_size_in_bytes; + page_extra_ = Page::kNonCodeObjectAreaSize % object_size_in_bytes; } // The limit of allocation for a page in this space. virtual Address PageAllocationLimit(Page* page) { - return page->ObjectAreaEnd() - page_extra_; + return page->area_end() - page_extra_; } int object_size_in_bytes() { return object_size_in_bytes_; } @@ -2387,7 +2404,7 @@ class MapSpace : public FixedSpace { #endif private: - static const int kMapsPerPage = Page::kObjectAreaSize / Map::kSize; + static const int kMapsPerPage = Page::kNonCodeObjectAreaSize / Map::kSize; // Do map space compaction if there is a page gap. int CompactionThreshold() { diff --git a/deps/v8/src/store-buffer.cc b/deps/v8/src/store-buffer.cc index 9022b3be83..385215573d 100644 --- a/deps/v8/src/store-buffer.cc +++ b/deps/v8/src/store-buffer.cc @@ -453,14 +453,14 @@ void StoreBuffer::FindPointersToNewSpaceInRegion( // Compute start address of the first map following given addr. static inline Address MapStartAlign(Address addr) { - Address page = Page::FromAddress(addr)->ObjectAreaStart(); + Address page = Page::FromAddress(addr)->area_start(); return page + (((addr - page) + (Map::kSize - 1)) / Map::kSize * Map::kSize); } // Compute end address of the first map preceding given addr. static inline Address MapEndAlign(Address addr) { - Address page = Page::FromAllocationTop(addr)->ObjectAreaStart(); + Address page = Page::FromAllocationTop(addr)->area_start(); return page + ((addr - page) / Map::kSize * Map::kSize); } @@ -523,8 +523,8 @@ void StoreBuffer::FindPointersToNewSpaceOnPage( Page* page, RegionCallback region_callback, ObjectSlotCallback slot_callback) { - Address visitable_start = page->ObjectAreaStart(); - Address end_of_page = page->ObjectAreaEnd(); + Address visitable_start = page->area_start(); + Address end_of_page = page->area_end(); Address visitable_end = visitable_start; diff --git a/deps/v8/src/token.h b/deps/v8/src/token.h index b305c88a30..1eeb60d876 100644 --- a/deps/v8/src/token.h +++ b/deps/v8/src/token.h @@ -173,7 +173,6 @@ namespace internal { K(EXPORT, "export", 0) \ K(IMPORT, "import", 0) \ K(LET, "let", 0) \ - K(MODULE, "module", 0) \ \ /* Illegal token - not able to scan. */ \ T(ILLEGAL, "ILLEGAL", 0) \ diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc index 0f50f1c643..f0af68de44 100644 --- a/deps/v8/src/version.cc +++ b/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 9 -#define BUILD_NUMBER 9 +#define BUILD_NUMBER 11 #define PATCH_LEVEL 0 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc index 50572201cc..9c03053afe 100644 --- a/deps/v8/src/x64/full-codegen-x64.cc +++ b/deps/v8/src/x64/full-codegen-x64.cc @@ -100,6 +100,11 @@ class JumpPatchSite BASE_EMBEDDED { }; +int FullCodeGenerator::self_optimization_header_size() { + return 20; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right, with the // return address on top of them. The actual argument count matches the @@ -120,13 +125,6 @@ void FullCodeGenerator::Generate() { SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); -#ifdef DEBUG - if (strlen(FLAG_stop_at) > 0 && - info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { - __ int3(); - } -#endif - // We can optionally optimize based on counters rather than statistical // sampling. if (info->ShouldSelfOptimize()) { @@ -134,6 +132,7 @@ void FullCodeGenerator::Generate() { PrintF("[adding self-optimization header to %s]\n", *info->function()->debug_name()->ToCString()); } + has_self_optimization_header_ = true; MaybeObject* maybe_cell = isolate()->heap()->AllocateJSGlobalPropertyCell( Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt)); JSGlobalPropertyCell* cell; @@ -145,9 +144,17 @@ void FullCodeGenerator::Generate() { Handle compile_stub( isolate()->builtins()->builtin(Builtins::kLazyRecompile)); __ j(zero, compile_stub, RelocInfo::CODE_TARGET); + ASSERT(masm_->pc_offset() == self_optimization_header_size()); } } +#ifdef DEBUG + if (strlen(FLAG_stop_at) > 0 && + info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { + __ int3(); + } +#endif + // Strict mode functions and builtins need to replace the receiver // with undefined when called as functions (without an explicit // receiver object). rcx is zero for method calls and non-zero for diff --git a/deps/v8/src/zone.h b/deps/v8/src/zone.h index 25c4f9a7a4..bc092b5f5e 100644 --- a/deps/v8/src/zone.h +++ b/deps/v8/src/zone.h @@ -30,6 +30,7 @@ #include "allocation.h" #include "checks.h" +#include "hashmap.h" #include "globals.h" #include "list.h" #include "splay-tree.h" @@ -239,6 +240,8 @@ class ZoneSplayTree: public SplayTree { }; +typedef TemplateHashMap ZoneHashMap; + } } // namespace v8::internal #endif // V8_ZONE_H_ diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc index c654dfa8bb..769fe7be29 100644 --- a/deps/v8/test/cctest/test-alloc.cc +++ b/deps/v8/test/cctest/test-alloc.cc @@ -88,7 +88,7 @@ static MaybeObject* AllocateAfterFailures() { static const int kLargeObjectSpaceFillerLength = 300000; static const int kLargeObjectSpaceFillerSize = FixedArray::SizeFor( kLargeObjectSpaceFillerLength); - ASSERT(kLargeObjectSpaceFillerSize > heap->MaxObjectSizeInPagedSpace()); + ASSERT(kLargeObjectSpaceFillerSize > heap->old_pointer_space()->AreaSize()); while (heap->OldGenerationSpaceAvailable() > kLargeObjectSpaceFillerSize) { CHECK(!heap->AllocateFixedArray(kLargeObjectSpaceFillerLength, TENURED)-> IsFailure()); @@ -214,11 +214,13 @@ TEST(CodeRange) { while (total_allocated < 5 * code_range_size) { if (current_allocated < code_range_size / 10) { // Allocate a block. - // Geometrically distributed sizes, greater than Page::kMaxHeapObjectSize. + // Geometrically distributed sizes, greater than + // Page::kMaxNonCodeHeapObjectSize (which is greater than code page area). // TODO(gc): instead of using 3 use some contant based on code_range_size // kMaxHeapObjectSize. - size_t requested = (Page::kMaxHeapObjectSize << (Pseudorandom() % 3)) + - Pseudorandom() % 5000 + 1; + size_t requested = + (Page::kMaxNonCodeHeapObjectSize << (Pseudorandom() % 3)) + + Pseudorandom() % 5000 + 1; size_t allocated = 0; Address base = code_range->AllocateRawMemory(requested, &allocated); CHECK(base != NULL); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 8cd73f2a84..a7e45d18ef 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -12331,18 +12331,21 @@ THREADED_TEST(PixelArray) { i::Handle value(i::Smi::FromInt(2)); i::Handle no_failure; - no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode); + no_failure = + i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode); ASSERT(!no_failure.is_null()); i::USE(no_failure); CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); *value.location() = i::Smi::FromInt(256); - no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode); + no_failure = + i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode); ASSERT(!no_failure.is_null()); i::USE(no_failure); CHECK_EQ(255, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); *value.location() = i::Smi::FromInt(-1); - no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode); + no_failure = + i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode); ASSERT(!no_failure.is_null()); i::USE(no_failure); CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index bf7e91b268..a6f04b308d 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -677,7 +677,7 @@ TEST(TakeHeapSnapshotAborting) { LocalContext env; const int snapshots_count = v8::HeapProfiler::GetSnapshotsCount(); - TestActivityControl aborting_control(3); + TestActivityControl aborting_control(1); const v8::HeapSnapshot* no_snapshot = v8::HeapProfiler::TakeSnapshot(v8_str("abort"), v8::HeapSnapshot::kFull, diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc index a6dd83054b..10bacf5043 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/test-heap.cc @@ -676,7 +676,7 @@ TEST(JSArray) { CHECK(array->HasFastTypeElements()); // array[length] = name. - array->SetElement(0, *name, kNonStrictMode, true)->ToObjectChecked(); + array->SetElement(0, *name, NONE, kNonStrictMode)->ToObjectChecked(); CHECK_EQ(Smi::FromInt(1), array->length()); CHECK_EQ(array->GetElement(0), *name); @@ -691,7 +691,7 @@ TEST(JSArray) { CHECK(array->HasDictionaryElements()); // Must be in slow mode. // array[length] = name. - array->SetElement(int_length, *name, kNonStrictMode, true)->ToObjectChecked(); + array->SetElement(int_length, *name, NONE, kNonStrictMode)->ToObjectChecked(); uint32_t new_int_length = 0; CHECK(array->length()->ToArrayIndex(&new_int_length)); CHECK_EQ(static_cast(int_length), new_int_length - 1); @@ -718,8 +718,8 @@ TEST(JSObjectCopy) { obj->SetProperty( *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetElement(0, *first, kNonStrictMode, true)->ToObjectChecked(); - obj->SetElement(1, *second, kNonStrictMode, true)->ToObjectChecked(); + obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked(); + obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); // Make the clone. Handle clone = Copy(obj); @@ -737,8 +737,8 @@ TEST(JSObjectCopy) { clone->SetProperty( *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); - clone->SetElement(0, *second, kNonStrictMode, true)->ToObjectChecked(); - clone->SetElement(1, *first, kNonStrictMode, true)->ToObjectChecked(); + clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked(); + clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked(); CHECK_EQ(obj->GetElement(1), clone->GetElement(0)); CHECK_EQ(obj->GetElement(0), clone->GetElement(1)); @@ -820,7 +820,7 @@ TEST(Iteration) { FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED); // Allocate a large string (for large object space). - int large_size = HEAP->MaxObjectSizeInPagedSpace() + 1; + int large_size = Page::kMaxNonCodeHeapObjectSize + 1; char* str = new char[large_size]; for (int i = 0; i < large_size - 1; ++i) str[i] = 'a'; str[large_size - 1] = '\0'; diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc index 2535f10c03..973af19662 100644 --- a/deps/v8/test/cctest/test-mark-compact.cc +++ b/deps/v8/test/cctest/test-mark-compact.cc @@ -94,7 +94,7 @@ TEST(Promotion) { // Allocate a fixed array in the new space. int array_size = - (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / + (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) / (kPointerSize * 4); Object* obj = HEAP->AllocateFixedArray(array_size)->ToObjectChecked(); @@ -125,7 +125,7 @@ TEST(NoPromotion) { // Allocate a big Fixed array in the new space. int max_size = - Min(HEAP->MaxObjectSizeInPagedSpace(), HEAP->MaxObjectSizeInNewSpace()); + Min(Page::kMaxNonCodeHeapObjectSize, HEAP->MaxObjectSizeInNewSpace()); int length = (max_size - FixedArray::kHeaderSize) / (2*kPointerSize); Object* obj = i::Isolate::Current()->heap()->AllocateFixedArray(length)-> @@ -542,7 +542,7 @@ TEST(BootUpMemoryUse) { if (v8::internal::Snapshot::IsEnabled()) { CHECK_LE(booted_memory - initial_memory, 6532 * 1024); // 6388. } else { - CHECK_LE(booted_memory - initial_memory, 6686 * 1024); // 6456 + CHECK_LE(booted_memory - initial_memory, 6940 * 1024); // 6456 } } } diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index b5c1a09763..e426e7bd21 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -558,7 +558,8 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { TEST(LinearAllocation) { v8::V8::Initialize(); int new_space_max = 512 * KB; - int paged_space_max = Page::kMaxHeapObjectSize; + int paged_space_max = Page::kMaxNonCodeHeapObjectSize; + int code_space_max = HEAP->code_space()->AreaSize(); for (int size = 1000; size < 5 * MB; size += size >> 1) { size &= ~8; // Round. @@ -568,7 +569,7 @@ TEST(LinearAllocation) { new_space_size, paged_space_size, // Old pointer space. paged_space_size, // Old data space. - HEAP->code_space()->RoundSizeDownToObjectAlignment(paged_space_size), + HEAP->code_space()->RoundSizeDownToObjectAlignment(code_space_max), HEAP->map_space()->RoundSizeDownToObjectAlignment(paged_space_size), HEAP->cell_space()->RoundSizeDownToObjectAlignment(paged_space_size), size); // Large object space. @@ -604,7 +605,7 @@ TEST(LinearAllocation) { int old_page_fullness = i % Page::kPageSize; int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize; if (page_fullness < old_page_fullness || - page_fullness > Page::kObjectAreaSize) { + page_fullness > HEAP->old_pointer_space()->AreaSize()) { i = RoundUp(i, Page::kPageSize); pointer_last = NULL; } @@ -624,7 +625,7 @@ TEST(LinearAllocation) { int old_page_fullness = i % Page::kPageSize; int page_fullness = (i + kSmallStringSize) % Page::kPageSize; if (page_fullness < old_page_fullness || - page_fullness > Page::kObjectAreaSize) { + page_fullness > HEAP->old_data_space()->AreaSize()) { i = RoundUp(i, Page::kPageSize); data_last = NULL; } @@ -642,7 +643,7 @@ TEST(LinearAllocation) { int old_page_fullness = i % Page::kPageSize; int page_fullness = (i + kMapSize) % Page::kPageSize; if (page_fullness < old_page_fullness || - page_fullness > Page::kObjectAreaSize) { + page_fullness > HEAP->map_space()->AreaSize()) { i = RoundUp(i, Page::kPageSize); map_last = NULL; } @@ -653,7 +654,7 @@ TEST(LinearAllocation) { map_last = obj; } - if (size > Page::kObjectAreaSize) { + if (size > Page::kMaxNonCodeHeapObjectSize) { // Support for reserving space in large object space is not there yet, // but using an always-allocate scope is fine for now. AlwaysAllocateScope always; diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc index 6e495bc169..92de2a60fa 100644 --- a/deps/v8/test/cctest/test-spaces.cc +++ b/deps/v8/test/cctest/test-spaces.cc @@ -191,9 +191,10 @@ TEST(NewSpace) { HEAP->ReservedSemiSpaceSize())); CHECK(new_space.HasBeenSetUp()); - while (new_space.Available() >= Page::kMaxHeapObjectSize) { + while (new_space.Available() >= Page::kMaxNonCodeHeapObjectSize) { Object* obj = - new_space.AllocateRaw(Page::kMaxHeapObjectSize)->ToObjectUnchecked(); + new_space.AllocateRaw(Page::kMaxNonCodeHeapObjectSize)-> + ToObjectUnchecked(); CHECK(new_space.Contains(HeapObject::cast(obj))); } @@ -223,7 +224,7 @@ TEST(OldSpace) { CHECK(s->SetUp()); while (s->Available() > 0) { - s->AllocateRaw(Page::kMaxHeapObjectSize)->ToObjectUnchecked(); + s->AllocateRaw(Page::kMaxNonCodeHeapObjectSize)->ToObjectUnchecked(); } s->TearDown(); diff --git a/deps/v8/test/mjsunit/get-own-property-descriptor.js b/deps/v8/test/mjsunit/get-own-property-descriptor.js index abb2420034..159c63bcc1 100644 --- a/deps/v8/test/mjsunit/get-own-property-descriptor.js +++ b/deps/v8/test/mjsunit/get-own-property-descriptor.js @@ -73,7 +73,7 @@ assertEquals(descObjectElement.value, 42); var a = new String('foobar'); for (var i = 0; i < a.length; i++) { var descStringObject = Object.getOwnPropertyDescriptor(a, i); - assertFalse(descStringObject.enumerable); + assertTrue(descStringObject.enumerable); assertFalse(descStringObject.configurable); assertFalse(descStringObject.writable); assertEquals(descStringObject.value, a.substring(i, i+1)); diff --git a/deps/v8/test/mjsunit/harmony/module-parsing.js b/deps/v8/test/mjsunit/harmony/module-parsing.js index ac398636da..5a5e82fdb1 100644 --- a/deps/v8/test/mjsunit/harmony/module-parsing.js +++ b/deps/v8/test/mjsunit/harmony/module-parsing.js @@ -63,18 +63,28 @@ module E3 = E1.F // Check that ASI does not interfere. -module -X +module X { let x } -module -Y +module Y = X -module -Z +module Z at "file://local" + + +// Check that 'module' still works as an identifier. + +var module +module = {} +module["a"] = 6 +function module() {} +function f(module) { return module } +try {} catch (module) {} + +module +v = 20 diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status index 2d22fe9075..a1b927097a 100644 --- a/deps/v8/test/mjsunit/mjsunit.status +++ b/deps/v8/test/mjsunit/mjsunit.status @@ -1,4 +1,4 @@ -# Copyright 2011 the V8 project authors. All rights reserved. +# 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: @@ -65,6 +65,9 @@ regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug debug-liveedit-check-stack: SKIP debug-liveedit-patch-positions-replace: SKIP +# Test Crankshaft compilation time. Expected to take too long in debug mode. +regress/regress-1969: PASS, SKIP if $mode == debug + ############################################################################## [ $isolates ] diff --git a/deps/v8/test/mjsunit/object-define-property.js b/deps/v8/test/mjsunit/object-define-property.js index ee6083a899..432fbdf7fc 100644 --- a/deps/v8/test/mjsunit/object-define-property.js +++ b/deps/v8/test/mjsunit/object-define-property.js @@ -1053,4 +1053,25 @@ for (var i = 0; i < 1000; i++) { // Non-enumerable property forces dictionary mode. Object.defineProperty(o, i, {value: i, enumerable: false}); } -assertEquals(999, o[999]); \ No newline at end of file +assertEquals(999, o[999]); + + +// Regression test: Bizzare behavior on non-strict arguments object. +(function test(arg0) { + // Here arguments[0] is a fast alias on arg0. + Object.defineProperty(arguments, "0", { + value:1, + enumerable:false + }); + // Here arguments[0] is a slow alias on arg0. + Object.defineProperty(arguments, "0", { + value:2, + writable:false + }); + // Here arguments[0] is no alias at all. + Object.defineProperty(arguments, "0", { + value:3 + }); + assertEquals(2, arg0); + assertEquals(3, arguments[0]); +})(0); diff --git a/deps/v8/test/mjsunit/regress/regress-1969.js b/deps/v8/test/mjsunit/regress/regress-1969.js new file mode 100644 index 0000000000..2728c2cae7 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1969.js @@ -0,0 +1,5045 @@ +// 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. + +// Flags: --allow-natives-syntax + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +var start = (new Date()).getTime(); +var array = f(); +var end = (new Date()).getTime(); + +// Assert that recompiling and executing f() takes less than a second. +assertTrue((end - start) < 1000); + +for (var i = 0; i < 5000; i++) assertEquals(0, array[i]); + +function f() { + var a = new Array(5000); + a[0]=0; + a[1]=0; + a[2]=0; + a[3]=0; + a[4]=0; + a[5]=0; + a[6]=0; + a[7]=0; + a[8]=0; + a[9]=0; + a[10]=0; + a[11]=0; + a[12]=0; + a[13]=0; + a[14]=0; + a[15]=0; + a[16]=0; + a[17]=0; + a[18]=0; + a[19]=0; + a[20]=0; + a[21]=0; + a[22]=0; + a[23]=0; + a[24]=0; + a[25]=0; + a[26]=0; + a[27]=0; + a[28]=0; + a[29]=0; + a[30]=0; + a[31]=0; + a[32]=0; + a[33]=0; + a[34]=0; + a[35]=0; + a[36]=0; + a[37]=0; + a[38]=0; + a[39]=0; + a[40]=0; + a[41]=0; + a[42]=0; + a[43]=0; + a[44]=0; + a[45]=0; + a[46]=0; + a[47]=0; + a[48]=0; + a[49]=0; + a[50]=0; + a[51]=0; + a[52]=0; + a[53]=0; + a[54]=0; + a[55]=0; + a[56]=0; + a[57]=0; + a[58]=0; + a[59]=0; + a[60]=0; + a[61]=0; + a[62]=0; + a[63]=0; + a[64]=0; + a[65]=0; + a[66]=0; + a[67]=0; + a[68]=0; + a[69]=0; + a[70]=0; + a[71]=0; + a[72]=0; + a[73]=0; + a[74]=0; + a[75]=0; + a[76]=0; + a[77]=0; + a[78]=0; + a[79]=0; + a[80]=0; + a[81]=0; + a[82]=0; + a[83]=0; + a[84]=0; + a[85]=0; + a[86]=0; + a[87]=0; + a[88]=0; + a[89]=0; + a[90]=0; + a[91]=0; + a[92]=0; + a[93]=0; + a[94]=0; + a[95]=0; + a[96]=0; + a[97]=0; + a[98]=0; + a[99]=0; + a[100]=0; + a[101]=0; + a[102]=0; + a[103]=0; + a[104]=0; + a[105]=0; + a[106]=0; + a[107]=0; + a[108]=0; + a[109]=0; + a[110]=0; + a[111]=0; + a[112]=0; + a[113]=0; + a[114]=0; + a[115]=0; + a[116]=0; + a[117]=0; + a[118]=0; + a[119]=0; + a[120]=0; + a[121]=0; + a[122]=0; + a[123]=0; + a[124]=0; + a[125]=0; + a[126]=0; + a[127]=0; + a[128]=0; + a[129]=0; + a[130]=0; + a[131]=0; + a[132]=0; + a[133]=0; + a[134]=0; + a[135]=0; + a[136]=0; + a[137]=0; + a[138]=0; + a[139]=0; + a[140]=0; + a[141]=0; + a[142]=0; + a[143]=0; + a[144]=0; + a[145]=0; + a[146]=0; + a[147]=0; + a[148]=0; + a[149]=0; + a[150]=0; + a[151]=0; + a[152]=0; + a[153]=0; + a[154]=0; + a[155]=0; + a[156]=0; + a[157]=0; + a[158]=0; + a[159]=0; + a[160]=0; + a[161]=0; + a[162]=0; + a[163]=0; + a[164]=0; + a[165]=0; + a[166]=0; + a[167]=0; + a[168]=0; + a[169]=0; + a[170]=0; + a[171]=0; + a[172]=0; + a[173]=0; + a[174]=0; + a[175]=0; + a[176]=0; + a[177]=0; + a[178]=0; + a[179]=0; + a[180]=0; + a[181]=0; + a[182]=0; + a[183]=0; + a[184]=0; + a[185]=0; + a[186]=0; + a[187]=0; + a[188]=0; + a[189]=0; + a[190]=0; + a[191]=0; + a[192]=0; + a[193]=0; + a[194]=0; + a[195]=0; + a[196]=0; + a[197]=0; + a[198]=0; + a[199]=0; + a[200]=0; + a[201]=0; + a[202]=0; + a[203]=0; + a[204]=0; + a[205]=0; + a[206]=0; + a[207]=0; + a[208]=0; + a[209]=0; + a[210]=0; + a[211]=0; + a[212]=0; + a[213]=0; + a[214]=0; + a[215]=0; + a[216]=0; + a[217]=0; + a[218]=0; + a[219]=0; + a[220]=0; + a[221]=0; + a[222]=0; + a[223]=0; + a[224]=0; + a[225]=0; + a[226]=0; + a[227]=0; + a[228]=0; + a[229]=0; + a[230]=0; + a[231]=0; + a[232]=0; + a[233]=0; + a[234]=0; + a[235]=0; + a[236]=0; + a[237]=0; + a[238]=0; + a[239]=0; + a[240]=0; + a[241]=0; + a[242]=0; + a[243]=0; + a[244]=0; + a[245]=0; + a[246]=0; + a[247]=0; + a[248]=0; + a[249]=0; + a[250]=0; + a[251]=0; + a[252]=0; + a[253]=0; + a[254]=0; + a[255]=0; + a[256]=0; + a[257]=0; + a[258]=0; + a[259]=0; + a[260]=0; + a[261]=0; + a[262]=0; + a[263]=0; + a[264]=0; + a[265]=0; + a[266]=0; + a[267]=0; + a[268]=0; + a[269]=0; + a[270]=0; + a[271]=0; + a[272]=0; + a[273]=0; + a[274]=0; + a[275]=0; + a[276]=0; + a[277]=0; + a[278]=0; + a[279]=0; + a[280]=0; + a[281]=0; + a[282]=0; + a[283]=0; + a[284]=0; + a[285]=0; + a[286]=0; + a[287]=0; + a[288]=0; + a[289]=0; + a[290]=0; + a[291]=0; + a[292]=0; + a[293]=0; + a[294]=0; + a[295]=0; + a[296]=0; + a[297]=0; + a[298]=0; + a[299]=0; + a[300]=0; + a[301]=0; + a[302]=0; + a[303]=0; + a[304]=0; + a[305]=0; + a[306]=0; + a[307]=0; + a[308]=0; + a[309]=0; + a[310]=0; + a[311]=0; + a[312]=0; + a[313]=0; + a[314]=0; + a[315]=0; + a[316]=0; + a[317]=0; + a[318]=0; + a[319]=0; + a[320]=0; + a[321]=0; + a[322]=0; + a[323]=0; + a[324]=0; + a[325]=0; + a[326]=0; + a[327]=0; + a[328]=0; + a[329]=0; + a[330]=0; + a[331]=0; + a[332]=0; + a[333]=0; + a[334]=0; + a[335]=0; + a[336]=0; + a[337]=0; + a[338]=0; + a[339]=0; + a[340]=0; + a[341]=0; + a[342]=0; + a[343]=0; + a[344]=0; + a[345]=0; + a[346]=0; + a[347]=0; + a[348]=0; + a[349]=0; + a[350]=0; + a[351]=0; + a[352]=0; + a[353]=0; + a[354]=0; + a[355]=0; + a[356]=0; + a[357]=0; + a[358]=0; + a[359]=0; + a[360]=0; + a[361]=0; + a[362]=0; + a[363]=0; + a[364]=0; + a[365]=0; + a[366]=0; + a[367]=0; + a[368]=0; + a[369]=0; + a[370]=0; + a[371]=0; + a[372]=0; + a[373]=0; + a[374]=0; + a[375]=0; + a[376]=0; + a[377]=0; + a[378]=0; + a[379]=0; + a[380]=0; + a[381]=0; + a[382]=0; + a[383]=0; + a[384]=0; + a[385]=0; + a[386]=0; + a[387]=0; + a[388]=0; + a[389]=0; + a[390]=0; + a[391]=0; + a[392]=0; + a[393]=0; + a[394]=0; + a[395]=0; + a[396]=0; + a[397]=0; + a[398]=0; + a[399]=0; + a[400]=0; + a[401]=0; + a[402]=0; + a[403]=0; + a[404]=0; + a[405]=0; + a[406]=0; + a[407]=0; + a[408]=0; + a[409]=0; + a[410]=0; + a[411]=0; + a[412]=0; + a[413]=0; + a[414]=0; + a[415]=0; + a[416]=0; + a[417]=0; + a[418]=0; + a[419]=0; + a[420]=0; + a[421]=0; + a[422]=0; + a[423]=0; + a[424]=0; + a[425]=0; + a[426]=0; + a[427]=0; + a[428]=0; + a[429]=0; + a[430]=0; + a[431]=0; + a[432]=0; + a[433]=0; + a[434]=0; + a[435]=0; + a[436]=0; + a[437]=0; + a[438]=0; + a[439]=0; + a[440]=0; + a[441]=0; + a[442]=0; + a[443]=0; + a[444]=0; + a[445]=0; + a[446]=0; + a[447]=0; + a[448]=0; + a[449]=0; + a[450]=0; + a[451]=0; + a[452]=0; + a[453]=0; + a[454]=0; + a[455]=0; + a[456]=0; + a[457]=0; + a[458]=0; + a[459]=0; + a[460]=0; + a[461]=0; + a[462]=0; + a[463]=0; + a[464]=0; + a[465]=0; + a[466]=0; + a[467]=0; + a[468]=0; + a[469]=0; + a[470]=0; + a[471]=0; + a[472]=0; + a[473]=0; + a[474]=0; + a[475]=0; + a[476]=0; + a[477]=0; + a[478]=0; + a[479]=0; + a[480]=0; + a[481]=0; + a[482]=0; + a[483]=0; + a[484]=0; + a[485]=0; + a[486]=0; + a[487]=0; + a[488]=0; + a[489]=0; + a[490]=0; + a[491]=0; + a[492]=0; + a[493]=0; + a[494]=0; + a[495]=0; + a[496]=0; + a[497]=0; + a[498]=0; + a[499]=0; + a[500]=0; + a[501]=0; + a[502]=0; + a[503]=0; + a[504]=0; + a[505]=0; + a[506]=0; + a[507]=0; + a[508]=0; + a[509]=0; + a[510]=0; + a[511]=0; + a[512]=0; + a[513]=0; + a[514]=0; + a[515]=0; + a[516]=0; + a[517]=0; + a[518]=0; + a[519]=0; + a[520]=0; + a[521]=0; + a[522]=0; + a[523]=0; + a[524]=0; + a[525]=0; + a[526]=0; + a[527]=0; + a[528]=0; + a[529]=0; + a[530]=0; + a[531]=0; + a[532]=0; + a[533]=0; + a[534]=0; + a[535]=0; + a[536]=0; + a[537]=0; + a[538]=0; + a[539]=0; + a[540]=0; + a[541]=0; + a[542]=0; + a[543]=0; + a[544]=0; + a[545]=0; + a[546]=0; + a[547]=0; + a[548]=0; + a[549]=0; + a[550]=0; + a[551]=0; + a[552]=0; + a[553]=0; + a[554]=0; + a[555]=0; + a[556]=0; + a[557]=0; + a[558]=0; + a[559]=0; + a[560]=0; + a[561]=0; + a[562]=0; + a[563]=0; + a[564]=0; + a[565]=0; + a[566]=0; + a[567]=0; + a[568]=0; + a[569]=0; + a[570]=0; + a[571]=0; + a[572]=0; + a[573]=0; + a[574]=0; + a[575]=0; + a[576]=0; + a[577]=0; + a[578]=0; + a[579]=0; + a[580]=0; + a[581]=0; + a[582]=0; + a[583]=0; + a[584]=0; + a[585]=0; + a[586]=0; + a[587]=0; + a[588]=0; + a[589]=0; + a[590]=0; + a[591]=0; + a[592]=0; + a[593]=0; + a[594]=0; + a[595]=0; + a[596]=0; + a[597]=0; + a[598]=0; + a[599]=0; + a[600]=0; + a[601]=0; + a[602]=0; + a[603]=0; + a[604]=0; + a[605]=0; + a[606]=0; + a[607]=0; + a[608]=0; + a[609]=0; + a[610]=0; + a[611]=0; + a[612]=0; + a[613]=0; + a[614]=0; + a[615]=0; + a[616]=0; + a[617]=0; + a[618]=0; + a[619]=0; + a[620]=0; + a[621]=0; + a[622]=0; + a[623]=0; + a[624]=0; + a[625]=0; + a[626]=0; + a[627]=0; + a[628]=0; + a[629]=0; + a[630]=0; + a[631]=0; + a[632]=0; + a[633]=0; + a[634]=0; + a[635]=0; + a[636]=0; + a[637]=0; + a[638]=0; + a[639]=0; + a[640]=0; + a[641]=0; + a[642]=0; + a[643]=0; + a[644]=0; + a[645]=0; + a[646]=0; + a[647]=0; + a[648]=0; + a[649]=0; + a[650]=0; + a[651]=0; + a[652]=0; + a[653]=0; + a[654]=0; + a[655]=0; + a[656]=0; + a[657]=0; + a[658]=0; + a[659]=0; + a[660]=0; + a[661]=0; + a[662]=0; + a[663]=0; + a[664]=0; + a[665]=0; + a[666]=0; + a[667]=0; + a[668]=0; + a[669]=0; + a[670]=0; + a[671]=0; + a[672]=0; + a[673]=0; + a[674]=0; + a[675]=0; + a[676]=0; + a[677]=0; + a[678]=0; + a[679]=0; + a[680]=0; + a[681]=0; + a[682]=0; + a[683]=0; + a[684]=0; + a[685]=0; + a[686]=0; + a[687]=0; + a[688]=0; + a[689]=0; + a[690]=0; + a[691]=0; + a[692]=0; + a[693]=0; + a[694]=0; + a[695]=0; + a[696]=0; + a[697]=0; + a[698]=0; + a[699]=0; + a[700]=0; + a[701]=0; + a[702]=0; + a[703]=0; + a[704]=0; + a[705]=0; + a[706]=0; + a[707]=0; + a[708]=0; + a[709]=0; + a[710]=0; + a[711]=0; + a[712]=0; + a[713]=0; + a[714]=0; + a[715]=0; + a[716]=0; + a[717]=0; + a[718]=0; + a[719]=0; + a[720]=0; + a[721]=0; + a[722]=0; + a[723]=0; + a[724]=0; + a[725]=0; + a[726]=0; + a[727]=0; + a[728]=0; + a[729]=0; + a[730]=0; + a[731]=0; + a[732]=0; + a[733]=0; + a[734]=0; + a[735]=0; + a[736]=0; + a[737]=0; + a[738]=0; + a[739]=0; + a[740]=0; + a[741]=0; + a[742]=0; + a[743]=0; + a[744]=0; + a[745]=0; + a[746]=0; + a[747]=0; + a[748]=0; + a[749]=0; + a[750]=0; + a[751]=0; + a[752]=0; + a[753]=0; + a[754]=0; + a[755]=0; + a[756]=0; + a[757]=0; + a[758]=0; + a[759]=0; + a[760]=0; + a[761]=0; + a[762]=0; + a[763]=0; + a[764]=0; + a[765]=0; + a[766]=0; + a[767]=0; + a[768]=0; + a[769]=0; + a[770]=0; + a[771]=0; + a[772]=0; + a[773]=0; + a[774]=0; + a[775]=0; + a[776]=0; + a[777]=0; + a[778]=0; + a[779]=0; + a[780]=0; + a[781]=0; + a[782]=0; + a[783]=0; + a[784]=0; + a[785]=0; + a[786]=0; + a[787]=0; + a[788]=0; + a[789]=0; + a[790]=0; + a[791]=0; + a[792]=0; + a[793]=0; + a[794]=0; + a[795]=0; + a[796]=0; + a[797]=0; + a[798]=0; + a[799]=0; + a[800]=0; + a[801]=0; + a[802]=0; + a[803]=0; + a[804]=0; + a[805]=0; + a[806]=0; + a[807]=0; + a[808]=0; + a[809]=0; + a[810]=0; + a[811]=0; + a[812]=0; + a[813]=0; + a[814]=0; + a[815]=0; + a[816]=0; + a[817]=0; + a[818]=0; + a[819]=0; + a[820]=0; + a[821]=0; + a[822]=0; + a[823]=0; + a[824]=0; + a[825]=0; + a[826]=0; + a[827]=0; + a[828]=0; + a[829]=0; + a[830]=0; + a[831]=0; + a[832]=0; + a[833]=0; + a[834]=0; + a[835]=0; + a[836]=0; + a[837]=0; + a[838]=0; + a[839]=0; + a[840]=0; + a[841]=0; + a[842]=0; + a[843]=0; + a[844]=0; + a[845]=0; + a[846]=0; + a[847]=0; + a[848]=0; + a[849]=0; + a[850]=0; + a[851]=0; + a[852]=0; + a[853]=0; + a[854]=0; + a[855]=0; + a[856]=0; + a[857]=0; + a[858]=0; + a[859]=0; + a[860]=0; + a[861]=0; + a[862]=0; + a[863]=0; + a[864]=0; + a[865]=0; + a[866]=0; + a[867]=0; + a[868]=0; + a[869]=0; + a[870]=0; + a[871]=0; + a[872]=0; + a[873]=0; + a[874]=0; + a[875]=0; + a[876]=0; + a[877]=0; + a[878]=0; + a[879]=0; + a[880]=0; + a[881]=0; + a[882]=0; + a[883]=0; + a[884]=0; + a[885]=0; + a[886]=0; + a[887]=0; + a[888]=0; + a[889]=0; + a[890]=0; + a[891]=0; + a[892]=0; + a[893]=0; + a[894]=0; + a[895]=0; + a[896]=0; + a[897]=0; + a[898]=0; + a[899]=0; + a[900]=0; + a[901]=0; + a[902]=0; + a[903]=0; + a[904]=0; + a[905]=0; + a[906]=0; + a[907]=0; + a[908]=0; + a[909]=0; + a[910]=0; + a[911]=0; + a[912]=0; + a[913]=0; + a[914]=0; + a[915]=0; + a[916]=0; + a[917]=0; + a[918]=0; + a[919]=0; + a[920]=0; + a[921]=0; + a[922]=0; + a[923]=0; + a[924]=0; + a[925]=0; + a[926]=0; + a[927]=0; + a[928]=0; + a[929]=0; + a[930]=0; + a[931]=0; + a[932]=0; + a[933]=0; + a[934]=0; + a[935]=0; + a[936]=0; + a[937]=0; + a[938]=0; + a[939]=0; + a[940]=0; + a[941]=0; + a[942]=0; + a[943]=0; + a[944]=0; + a[945]=0; + a[946]=0; + a[947]=0; + a[948]=0; + a[949]=0; + a[950]=0; + a[951]=0; + a[952]=0; + a[953]=0; + a[954]=0; + a[955]=0; + a[956]=0; + a[957]=0; + a[958]=0; + a[959]=0; + a[960]=0; + a[961]=0; + a[962]=0; + a[963]=0; + a[964]=0; + a[965]=0; + a[966]=0; + a[967]=0; + a[968]=0; + a[969]=0; + a[970]=0; + a[971]=0; + a[972]=0; + a[973]=0; + a[974]=0; + a[975]=0; + a[976]=0; + a[977]=0; + a[978]=0; + a[979]=0; + a[980]=0; + a[981]=0; + a[982]=0; + a[983]=0; + a[984]=0; + a[985]=0; + a[986]=0; + a[987]=0; + a[988]=0; + a[989]=0; + a[990]=0; + a[991]=0; + a[992]=0; + a[993]=0; + a[994]=0; + a[995]=0; + a[996]=0; + a[997]=0; + a[998]=0; + a[999]=0; + a[1000]=0; + a[1001]=0; + a[1002]=0; + a[1003]=0; + a[1004]=0; + a[1005]=0; + a[1006]=0; + a[1007]=0; + a[1008]=0; + a[1009]=0; + a[1010]=0; + a[1011]=0; + a[1012]=0; + a[1013]=0; + a[1014]=0; + a[1015]=0; + a[1016]=0; + a[1017]=0; + a[1018]=0; + a[1019]=0; + a[1020]=0; + a[1021]=0; + a[1022]=0; + a[1023]=0; + a[1024]=0; + a[1025]=0; + a[1026]=0; + a[1027]=0; + a[1028]=0; + a[1029]=0; + a[1030]=0; + a[1031]=0; + a[1032]=0; + a[1033]=0; + a[1034]=0; + a[1035]=0; + a[1036]=0; + a[1037]=0; + a[1038]=0; + a[1039]=0; + a[1040]=0; + a[1041]=0; + a[1042]=0; + a[1043]=0; + a[1044]=0; + a[1045]=0; + a[1046]=0; + a[1047]=0; + a[1048]=0; + a[1049]=0; + a[1050]=0; + a[1051]=0; + a[1052]=0; + a[1053]=0; + a[1054]=0; + a[1055]=0; + a[1056]=0; + a[1057]=0; + a[1058]=0; + a[1059]=0; + a[1060]=0; + a[1061]=0; + a[1062]=0; + a[1063]=0; + a[1064]=0; + a[1065]=0; + a[1066]=0; + a[1067]=0; + a[1068]=0; + a[1069]=0; + a[1070]=0; + a[1071]=0; + a[1072]=0; + a[1073]=0; + a[1074]=0; + a[1075]=0; + a[1076]=0; + a[1077]=0; + a[1078]=0; + a[1079]=0; + a[1080]=0; + a[1081]=0; + a[1082]=0; + a[1083]=0; + a[1084]=0; + a[1085]=0; + a[1086]=0; + a[1087]=0; + a[1088]=0; + a[1089]=0; + a[1090]=0; + a[1091]=0; + a[1092]=0; + a[1093]=0; + a[1094]=0; + a[1095]=0; + a[1096]=0; + a[1097]=0; + a[1098]=0; + a[1099]=0; + a[1100]=0; + a[1101]=0; + a[1102]=0; + a[1103]=0; + a[1104]=0; + a[1105]=0; + a[1106]=0; + a[1107]=0; + a[1108]=0; + a[1109]=0; + a[1110]=0; + a[1111]=0; + a[1112]=0; + a[1113]=0; + a[1114]=0; + a[1115]=0; + a[1116]=0; + a[1117]=0; + a[1118]=0; + a[1119]=0; + a[1120]=0; + a[1121]=0; + a[1122]=0; + a[1123]=0; + a[1124]=0; + a[1125]=0; + a[1126]=0; + a[1127]=0; + a[1128]=0; + a[1129]=0; + a[1130]=0; + a[1131]=0; + a[1132]=0; + a[1133]=0; + a[1134]=0; + a[1135]=0; + a[1136]=0; + a[1137]=0; + a[1138]=0; + a[1139]=0; + a[1140]=0; + a[1141]=0; + a[1142]=0; + a[1143]=0; + a[1144]=0; + a[1145]=0; + a[1146]=0; + a[1147]=0; + a[1148]=0; + a[1149]=0; + a[1150]=0; + a[1151]=0; + a[1152]=0; + a[1153]=0; + a[1154]=0; + a[1155]=0; + a[1156]=0; + a[1157]=0; + a[1158]=0; + a[1159]=0; + a[1160]=0; + a[1161]=0; + a[1162]=0; + a[1163]=0; + a[1164]=0; + a[1165]=0; + a[1166]=0; + a[1167]=0; + a[1168]=0; + a[1169]=0; + a[1170]=0; + a[1171]=0; + a[1172]=0; + a[1173]=0; + a[1174]=0; + a[1175]=0; + a[1176]=0; + a[1177]=0; + a[1178]=0; + a[1179]=0; + a[1180]=0; + a[1181]=0; + a[1182]=0; + a[1183]=0; + a[1184]=0; + a[1185]=0; + a[1186]=0; + a[1187]=0; + a[1188]=0; + a[1189]=0; + a[1190]=0; + a[1191]=0; + a[1192]=0; + a[1193]=0; + a[1194]=0; + a[1195]=0; + a[1196]=0; + a[1197]=0; + a[1198]=0; + a[1199]=0; + a[1200]=0; + a[1201]=0; + a[1202]=0; + a[1203]=0; + a[1204]=0; + a[1205]=0; + a[1206]=0; + a[1207]=0; + a[1208]=0; + a[1209]=0; + a[1210]=0; + a[1211]=0; + a[1212]=0; + a[1213]=0; + a[1214]=0; + a[1215]=0; + a[1216]=0; + a[1217]=0; + a[1218]=0; + a[1219]=0; + a[1220]=0; + a[1221]=0; + a[1222]=0; + a[1223]=0; + a[1224]=0; + a[1225]=0; + a[1226]=0; + a[1227]=0; + a[1228]=0; + a[1229]=0; + a[1230]=0; + a[1231]=0; + a[1232]=0; + a[1233]=0; + a[1234]=0; + a[1235]=0; + a[1236]=0; + a[1237]=0; + a[1238]=0; + a[1239]=0; + a[1240]=0; + a[1241]=0; + a[1242]=0; + a[1243]=0; + a[1244]=0; + a[1245]=0; + a[1246]=0; + a[1247]=0; + a[1248]=0; + a[1249]=0; + a[1250]=0; + a[1251]=0; + a[1252]=0; + a[1253]=0; + a[1254]=0; + a[1255]=0; + a[1256]=0; + a[1257]=0; + a[1258]=0; + a[1259]=0; + a[1260]=0; + a[1261]=0; + a[1262]=0; + a[1263]=0; + a[1264]=0; + a[1265]=0; + a[1266]=0; + a[1267]=0; + a[1268]=0; + a[1269]=0; + a[1270]=0; + a[1271]=0; + a[1272]=0; + a[1273]=0; + a[1274]=0; + a[1275]=0; + a[1276]=0; + a[1277]=0; + a[1278]=0; + a[1279]=0; + a[1280]=0; + a[1281]=0; + a[1282]=0; + a[1283]=0; + a[1284]=0; + a[1285]=0; + a[1286]=0; + a[1287]=0; + a[1288]=0; + a[1289]=0; + a[1290]=0; + a[1291]=0; + a[1292]=0; + a[1293]=0; + a[1294]=0; + a[1295]=0; + a[1296]=0; + a[1297]=0; + a[1298]=0; + a[1299]=0; + a[1300]=0; + a[1301]=0; + a[1302]=0; + a[1303]=0; + a[1304]=0; + a[1305]=0; + a[1306]=0; + a[1307]=0; + a[1308]=0; + a[1309]=0; + a[1310]=0; + a[1311]=0; + a[1312]=0; + a[1313]=0; + a[1314]=0; + a[1315]=0; + a[1316]=0; + a[1317]=0; + a[1318]=0; + a[1319]=0; + a[1320]=0; + a[1321]=0; + a[1322]=0; + a[1323]=0; + a[1324]=0; + a[1325]=0; + a[1326]=0; + a[1327]=0; + a[1328]=0; + a[1329]=0; + a[1330]=0; + a[1331]=0; + a[1332]=0; + a[1333]=0; + a[1334]=0; + a[1335]=0; + a[1336]=0; + a[1337]=0; + a[1338]=0; + a[1339]=0; + a[1340]=0; + a[1341]=0; + a[1342]=0; + a[1343]=0; + a[1344]=0; + a[1345]=0; + a[1346]=0; + a[1347]=0; + a[1348]=0; + a[1349]=0; + a[1350]=0; + a[1351]=0; + a[1352]=0; + a[1353]=0; + a[1354]=0; + a[1355]=0; + a[1356]=0; + a[1357]=0; + a[1358]=0; + a[1359]=0; + a[1360]=0; + a[1361]=0; + a[1362]=0; + a[1363]=0; + a[1364]=0; + a[1365]=0; + a[1366]=0; + a[1367]=0; + a[1368]=0; + a[1369]=0; + a[1370]=0; + a[1371]=0; + a[1372]=0; + a[1373]=0; + a[1374]=0; + a[1375]=0; + a[1376]=0; + a[1377]=0; + a[1378]=0; + a[1379]=0; + a[1380]=0; + a[1381]=0; + a[1382]=0; + a[1383]=0; + a[1384]=0; + a[1385]=0; + a[1386]=0; + a[1387]=0; + a[1388]=0; + a[1389]=0; + a[1390]=0; + a[1391]=0; + a[1392]=0; + a[1393]=0; + a[1394]=0; + a[1395]=0; + a[1396]=0; + a[1397]=0; + a[1398]=0; + a[1399]=0; + a[1400]=0; + a[1401]=0; + a[1402]=0; + a[1403]=0; + a[1404]=0; + a[1405]=0; + a[1406]=0; + a[1407]=0; + a[1408]=0; + a[1409]=0; + a[1410]=0; + a[1411]=0; + a[1412]=0; + a[1413]=0; + a[1414]=0; + a[1415]=0; + a[1416]=0; + a[1417]=0; + a[1418]=0; + a[1419]=0; + a[1420]=0; + a[1421]=0; + a[1422]=0; + a[1423]=0; + a[1424]=0; + a[1425]=0; + a[1426]=0; + a[1427]=0; + a[1428]=0; + a[1429]=0; + a[1430]=0; + a[1431]=0; + a[1432]=0; + a[1433]=0; + a[1434]=0; + a[1435]=0; + a[1436]=0; + a[1437]=0; + a[1438]=0; + a[1439]=0; + a[1440]=0; + a[1441]=0; + a[1442]=0; + a[1443]=0; + a[1444]=0; + a[1445]=0; + a[1446]=0; + a[1447]=0; + a[1448]=0; + a[1449]=0; + a[1450]=0; + a[1451]=0; + a[1452]=0; + a[1453]=0; + a[1454]=0; + a[1455]=0; + a[1456]=0; + a[1457]=0; + a[1458]=0; + a[1459]=0; + a[1460]=0; + a[1461]=0; + a[1462]=0; + a[1463]=0; + a[1464]=0; + a[1465]=0; + a[1466]=0; + a[1467]=0; + a[1468]=0; + a[1469]=0; + a[1470]=0; + a[1471]=0; + a[1472]=0; + a[1473]=0; + a[1474]=0; + a[1475]=0; + a[1476]=0; + a[1477]=0; + a[1478]=0; + a[1479]=0; + a[1480]=0; + a[1481]=0; + a[1482]=0; + a[1483]=0; + a[1484]=0; + a[1485]=0; + a[1486]=0; + a[1487]=0; + a[1488]=0; + a[1489]=0; + a[1490]=0; + a[1491]=0; + a[1492]=0; + a[1493]=0; + a[1494]=0; + a[1495]=0; + a[1496]=0; + a[1497]=0; + a[1498]=0; + a[1499]=0; + a[1500]=0; + a[1501]=0; + a[1502]=0; + a[1503]=0; + a[1504]=0; + a[1505]=0; + a[1506]=0; + a[1507]=0; + a[1508]=0; + a[1509]=0; + a[1510]=0; + a[1511]=0; + a[1512]=0; + a[1513]=0; + a[1514]=0; + a[1515]=0; + a[1516]=0; + a[1517]=0; + a[1518]=0; + a[1519]=0; + a[1520]=0; + a[1521]=0; + a[1522]=0; + a[1523]=0; + a[1524]=0; + a[1525]=0; + a[1526]=0; + a[1527]=0; + a[1528]=0; + a[1529]=0; + a[1530]=0; + a[1531]=0; + a[1532]=0; + a[1533]=0; + a[1534]=0; + a[1535]=0; + a[1536]=0; + a[1537]=0; + a[1538]=0; + a[1539]=0; + a[1540]=0; + a[1541]=0; + a[1542]=0; + a[1543]=0; + a[1544]=0; + a[1545]=0; + a[1546]=0; + a[1547]=0; + a[1548]=0; + a[1549]=0; + a[1550]=0; + a[1551]=0; + a[1552]=0; + a[1553]=0; + a[1554]=0; + a[1555]=0; + a[1556]=0; + a[1557]=0; + a[1558]=0; + a[1559]=0; + a[1560]=0; + a[1561]=0; + a[1562]=0; + a[1563]=0; + a[1564]=0; + a[1565]=0; + a[1566]=0; + a[1567]=0; + a[1568]=0; + a[1569]=0; + a[1570]=0; + a[1571]=0; + a[1572]=0; + a[1573]=0; + a[1574]=0; + a[1575]=0; + a[1576]=0; + a[1577]=0; + a[1578]=0; + a[1579]=0; + a[1580]=0; + a[1581]=0; + a[1582]=0; + a[1583]=0; + a[1584]=0; + a[1585]=0; + a[1586]=0; + a[1587]=0; + a[1588]=0; + a[1589]=0; + a[1590]=0; + a[1591]=0; + a[1592]=0; + a[1593]=0; + a[1594]=0; + a[1595]=0; + a[1596]=0; + a[1597]=0; + a[1598]=0; + a[1599]=0; + a[1600]=0; + a[1601]=0; + a[1602]=0; + a[1603]=0; + a[1604]=0; + a[1605]=0; + a[1606]=0; + a[1607]=0; + a[1608]=0; + a[1609]=0; + a[1610]=0; + a[1611]=0; + a[1612]=0; + a[1613]=0; + a[1614]=0; + a[1615]=0; + a[1616]=0; + a[1617]=0; + a[1618]=0; + a[1619]=0; + a[1620]=0; + a[1621]=0; + a[1622]=0; + a[1623]=0; + a[1624]=0; + a[1625]=0; + a[1626]=0; + a[1627]=0; + a[1628]=0; + a[1629]=0; + a[1630]=0; + a[1631]=0; + a[1632]=0; + a[1633]=0; + a[1634]=0; + a[1635]=0; + a[1636]=0; + a[1637]=0; + a[1638]=0; + a[1639]=0; + a[1640]=0; + a[1641]=0; + a[1642]=0; + a[1643]=0; + a[1644]=0; + a[1645]=0; + a[1646]=0; + a[1647]=0; + a[1648]=0; + a[1649]=0; + a[1650]=0; + a[1651]=0; + a[1652]=0; + a[1653]=0; + a[1654]=0; + a[1655]=0; + a[1656]=0; + a[1657]=0; + a[1658]=0; + a[1659]=0; + a[1660]=0; + a[1661]=0; + a[1662]=0; + a[1663]=0; + a[1664]=0; + a[1665]=0; + a[1666]=0; + a[1667]=0; + a[1668]=0; + a[1669]=0; + a[1670]=0; + a[1671]=0; + a[1672]=0; + a[1673]=0; + a[1674]=0; + a[1675]=0; + a[1676]=0; + a[1677]=0; + a[1678]=0; + a[1679]=0; + a[1680]=0; + a[1681]=0; + a[1682]=0; + a[1683]=0; + a[1684]=0; + a[1685]=0; + a[1686]=0; + a[1687]=0; + a[1688]=0; + a[1689]=0; + a[1690]=0; + a[1691]=0; + a[1692]=0; + a[1693]=0; + a[1694]=0; + a[1695]=0; + a[1696]=0; + a[1697]=0; + a[1698]=0; + a[1699]=0; + a[1700]=0; + a[1701]=0; + a[1702]=0; + a[1703]=0; + a[1704]=0; + a[1705]=0; + a[1706]=0; + a[1707]=0; + a[1708]=0; + a[1709]=0; + a[1710]=0; + a[1711]=0; + a[1712]=0; + a[1713]=0; + a[1714]=0; + a[1715]=0; + a[1716]=0; + a[1717]=0; + a[1718]=0; + a[1719]=0; + a[1720]=0; + a[1721]=0; + a[1722]=0; + a[1723]=0; + a[1724]=0; + a[1725]=0; + a[1726]=0; + a[1727]=0; + a[1728]=0; + a[1729]=0; + a[1730]=0; + a[1731]=0; + a[1732]=0; + a[1733]=0; + a[1734]=0; + a[1735]=0; + a[1736]=0; + a[1737]=0; + a[1738]=0; + a[1739]=0; + a[1740]=0; + a[1741]=0; + a[1742]=0; + a[1743]=0; + a[1744]=0; + a[1745]=0; + a[1746]=0; + a[1747]=0; + a[1748]=0; + a[1749]=0; + a[1750]=0; + a[1751]=0; + a[1752]=0; + a[1753]=0; + a[1754]=0; + a[1755]=0; + a[1756]=0; + a[1757]=0; + a[1758]=0; + a[1759]=0; + a[1760]=0; + a[1761]=0; + a[1762]=0; + a[1763]=0; + a[1764]=0; + a[1765]=0; + a[1766]=0; + a[1767]=0; + a[1768]=0; + a[1769]=0; + a[1770]=0; + a[1771]=0; + a[1772]=0; + a[1773]=0; + a[1774]=0; + a[1775]=0; + a[1776]=0; + a[1777]=0; + a[1778]=0; + a[1779]=0; + a[1780]=0; + a[1781]=0; + a[1782]=0; + a[1783]=0; + a[1784]=0; + a[1785]=0; + a[1786]=0; + a[1787]=0; + a[1788]=0; + a[1789]=0; + a[1790]=0; + a[1791]=0; + a[1792]=0; + a[1793]=0; + a[1794]=0; + a[1795]=0; + a[1796]=0; + a[1797]=0; + a[1798]=0; + a[1799]=0; + a[1800]=0; + a[1801]=0; + a[1802]=0; + a[1803]=0; + a[1804]=0; + a[1805]=0; + a[1806]=0; + a[1807]=0; + a[1808]=0; + a[1809]=0; + a[1810]=0; + a[1811]=0; + a[1812]=0; + a[1813]=0; + a[1814]=0; + a[1815]=0; + a[1816]=0; + a[1817]=0; + a[1818]=0; + a[1819]=0; + a[1820]=0; + a[1821]=0; + a[1822]=0; + a[1823]=0; + a[1824]=0; + a[1825]=0; + a[1826]=0; + a[1827]=0; + a[1828]=0; + a[1829]=0; + a[1830]=0; + a[1831]=0; + a[1832]=0; + a[1833]=0; + a[1834]=0; + a[1835]=0; + a[1836]=0; + a[1837]=0; + a[1838]=0; + a[1839]=0; + a[1840]=0; + a[1841]=0; + a[1842]=0; + a[1843]=0; + a[1844]=0; + a[1845]=0; + a[1846]=0; + a[1847]=0; + a[1848]=0; + a[1849]=0; + a[1850]=0; + a[1851]=0; + a[1852]=0; + a[1853]=0; + a[1854]=0; + a[1855]=0; + a[1856]=0; + a[1857]=0; + a[1858]=0; + a[1859]=0; + a[1860]=0; + a[1861]=0; + a[1862]=0; + a[1863]=0; + a[1864]=0; + a[1865]=0; + a[1866]=0; + a[1867]=0; + a[1868]=0; + a[1869]=0; + a[1870]=0; + a[1871]=0; + a[1872]=0; + a[1873]=0; + a[1874]=0; + a[1875]=0; + a[1876]=0; + a[1877]=0; + a[1878]=0; + a[1879]=0; + a[1880]=0; + a[1881]=0; + a[1882]=0; + a[1883]=0; + a[1884]=0; + a[1885]=0; + a[1886]=0; + a[1887]=0; + a[1888]=0; + a[1889]=0; + a[1890]=0; + a[1891]=0; + a[1892]=0; + a[1893]=0; + a[1894]=0; + a[1895]=0; + a[1896]=0; + a[1897]=0; + a[1898]=0; + a[1899]=0; + a[1900]=0; + a[1901]=0; + a[1902]=0; + a[1903]=0; + a[1904]=0; + a[1905]=0; + a[1906]=0; + a[1907]=0; + a[1908]=0; + a[1909]=0; + a[1910]=0; + a[1911]=0; + a[1912]=0; + a[1913]=0; + a[1914]=0; + a[1915]=0; + a[1916]=0; + a[1917]=0; + a[1918]=0; + a[1919]=0; + a[1920]=0; + a[1921]=0; + a[1922]=0; + a[1923]=0; + a[1924]=0; + a[1925]=0; + a[1926]=0; + a[1927]=0; + a[1928]=0; + a[1929]=0; + a[1930]=0; + a[1931]=0; + a[1932]=0; + a[1933]=0; + a[1934]=0; + a[1935]=0; + a[1936]=0; + a[1937]=0; + a[1938]=0; + a[1939]=0; + a[1940]=0; + a[1941]=0; + a[1942]=0; + a[1943]=0; + a[1944]=0; + a[1945]=0; + a[1946]=0; + a[1947]=0; + a[1948]=0; + a[1949]=0; + a[1950]=0; + a[1951]=0; + a[1952]=0; + a[1953]=0; + a[1954]=0; + a[1955]=0; + a[1956]=0; + a[1957]=0; + a[1958]=0; + a[1959]=0; + a[1960]=0; + a[1961]=0; + a[1962]=0; + a[1963]=0; + a[1964]=0; + a[1965]=0; + a[1966]=0; + a[1967]=0; + a[1968]=0; + a[1969]=0; + a[1970]=0; + a[1971]=0; + a[1972]=0; + a[1973]=0; + a[1974]=0; + a[1975]=0; + a[1976]=0; + a[1977]=0; + a[1978]=0; + a[1979]=0; + a[1980]=0; + a[1981]=0; + a[1982]=0; + a[1983]=0; + a[1984]=0; + a[1985]=0; + a[1986]=0; + a[1987]=0; + a[1988]=0; + a[1989]=0; + a[1990]=0; + a[1991]=0; + a[1992]=0; + a[1993]=0; + a[1994]=0; + a[1995]=0; + a[1996]=0; + a[1997]=0; + a[1998]=0; + a[1999]=0; + a[2000]=0; + a[2001]=0; + a[2002]=0; + a[2003]=0; + a[2004]=0; + a[2005]=0; + a[2006]=0; + a[2007]=0; + a[2008]=0; + a[2009]=0; + a[2010]=0; + a[2011]=0; + a[2012]=0; + a[2013]=0; + a[2014]=0; + a[2015]=0; + a[2016]=0; + a[2017]=0; + a[2018]=0; + a[2019]=0; + a[2020]=0; + a[2021]=0; + a[2022]=0; + a[2023]=0; + a[2024]=0; + a[2025]=0; + a[2026]=0; + a[2027]=0; + a[2028]=0; + a[2029]=0; + a[2030]=0; + a[2031]=0; + a[2032]=0; + a[2033]=0; + a[2034]=0; + a[2035]=0; + a[2036]=0; + a[2037]=0; + a[2038]=0; + a[2039]=0; + a[2040]=0; + a[2041]=0; + a[2042]=0; + a[2043]=0; + a[2044]=0; + a[2045]=0; + a[2046]=0; + a[2047]=0; + a[2048]=0; + a[2049]=0; + a[2050]=0; + a[2051]=0; + a[2052]=0; + a[2053]=0; + a[2054]=0; + a[2055]=0; + a[2056]=0; + a[2057]=0; + a[2058]=0; + a[2059]=0; + a[2060]=0; + a[2061]=0; + a[2062]=0; + a[2063]=0; + a[2064]=0; + a[2065]=0; + a[2066]=0; + a[2067]=0; + a[2068]=0; + a[2069]=0; + a[2070]=0; + a[2071]=0; + a[2072]=0; + a[2073]=0; + a[2074]=0; + a[2075]=0; + a[2076]=0; + a[2077]=0; + a[2078]=0; + a[2079]=0; + a[2080]=0; + a[2081]=0; + a[2082]=0; + a[2083]=0; + a[2084]=0; + a[2085]=0; + a[2086]=0; + a[2087]=0; + a[2088]=0; + a[2089]=0; + a[2090]=0; + a[2091]=0; + a[2092]=0; + a[2093]=0; + a[2094]=0; + a[2095]=0; + a[2096]=0; + a[2097]=0; + a[2098]=0; + a[2099]=0; + a[2100]=0; + a[2101]=0; + a[2102]=0; + a[2103]=0; + a[2104]=0; + a[2105]=0; + a[2106]=0; + a[2107]=0; + a[2108]=0; + a[2109]=0; + a[2110]=0; + a[2111]=0; + a[2112]=0; + a[2113]=0; + a[2114]=0; + a[2115]=0; + a[2116]=0; + a[2117]=0; + a[2118]=0; + a[2119]=0; + a[2120]=0; + a[2121]=0; + a[2122]=0; + a[2123]=0; + a[2124]=0; + a[2125]=0; + a[2126]=0; + a[2127]=0; + a[2128]=0; + a[2129]=0; + a[2130]=0; + a[2131]=0; + a[2132]=0; + a[2133]=0; + a[2134]=0; + a[2135]=0; + a[2136]=0; + a[2137]=0; + a[2138]=0; + a[2139]=0; + a[2140]=0; + a[2141]=0; + a[2142]=0; + a[2143]=0; + a[2144]=0; + a[2145]=0; + a[2146]=0; + a[2147]=0; + a[2148]=0; + a[2149]=0; + a[2150]=0; + a[2151]=0; + a[2152]=0; + a[2153]=0; + a[2154]=0; + a[2155]=0; + a[2156]=0; + a[2157]=0; + a[2158]=0; + a[2159]=0; + a[2160]=0; + a[2161]=0; + a[2162]=0; + a[2163]=0; + a[2164]=0; + a[2165]=0; + a[2166]=0; + a[2167]=0; + a[2168]=0; + a[2169]=0; + a[2170]=0; + a[2171]=0; + a[2172]=0; + a[2173]=0; + a[2174]=0; + a[2175]=0; + a[2176]=0; + a[2177]=0; + a[2178]=0; + a[2179]=0; + a[2180]=0; + a[2181]=0; + a[2182]=0; + a[2183]=0; + a[2184]=0; + a[2185]=0; + a[2186]=0; + a[2187]=0; + a[2188]=0; + a[2189]=0; + a[2190]=0; + a[2191]=0; + a[2192]=0; + a[2193]=0; + a[2194]=0; + a[2195]=0; + a[2196]=0; + a[2197]=0; + a[2198]=0; + a[2199]=0; + a[2200]=0; + a[2201]=0; + a[2202]=0; + a[2203]=0; + a[2204]=0; + a[2205]=0; + a[2206]=0; + a[2207]=0; + a[2208]=0; + a[2209]=0; + a[2210]=0; + a[2211]=0; + a[2212]=0; + a[2213]=0; + a[2214]=0; + a[2215]=0; + a[2216]=0; + a[2217]=0; + a[2218]=0; + a[2219]=0; + a[2220]=0; + a[2221]=0; + a[2222]=0; + a[2223]=0; + a[2224]=0; + a[2225]=0; + a[2226]=0; + a[2227]=0; + a[2228]=0; + a[2229]=0; + a[2230]=0; + a[2231]=0; + a[2232]=0; + a[2233]=0; + a[2234]=0; + a[2235]=0; + a[2236]=0; + a[2237]=0; + a[2238]=0; + a[2239]=0; + a[2240]=0; + a[2241]=0; + a[2242]=0; + a[2243]=0; + a[2244]=0; + a[2245]=0; + a[2246]=0; + a[2247]=0; + a[2248]=0; + a[2249]=0; + a[2250]=0; + a[2251]=0; + a[2252]=0; + a[2253]=0; + a[2254]=0; + a[2255]=0; + a[2256]=0; + a[2257]=0; + a[2258]=0; + a[2259]=0; + a[2260]=0; + a[2261]=0; + a[2262]=0; + a[2263]=0; + a[2264]=0; + a[2265]=0; + a[2266]=0; + a[2267]=0; + a[2268]=0; + a[2269]=0; + a[2270]=0; + a[2271]=0; + a[2272]=0; + a[2273]=0; + a[2274]=0; + a[2275]=0; + a[2276]=0; + a[2277]=0; + a[2278]=0; + a[2279]=0; + a[2280]=0; + a[2281]=0; + a[2282]=0; + a[2283]=0; + a[2284]=0; + a[2285]=0; + a[2286]=0; + a[2287]=0; + a[2288]=0; + a[2289]=0; + a[2290]=0; + a[2291]=0; + a[2292]=0; + a[2293]=0; + a[2294]=0; + a[2295]=0; + a[2296]=0; + a[2297]=0; + a[2298]=0; + a[2299]=0; + a[2300]=0; + a[2301]=0; + a[2302]=0; + a[2303]=0; + a[2304]=0; + a[2305]=0; + a[2306]=0; + a[2307]=0; + a[2308]=0; + a[2309]=0; + a[2310]=0; + a[2311]=0; + a[2312]=0; + a[2313]=0; + a[2314]=0; + a[2315]=0; + a[2316]=0; + a[2317]=0; + a[2318]=0; + a[2319]=0; + a[2320]=0; + a[2321]=0; + a[2322]=0; + a[2323]=0; + a[2324]=0; + a[2325]=0; + a[2326]=0; + a[2327]=0; + a[2328]=0; + a[2329]=0; + a[2330]=0; + a[2331]=0; + a[2332]=0; + a[2333]=0; + a[2334]=0; + a[2335]=0; + a[2336]=0; + a[2337]=0; + a[2338]=0; + a[2339]=0; + a[2340]=0; + a[2341]=0; + a[2342]=0; + a[2343]=0; + a[2344]=0; + a[2345]=0; + a[2346]=0; + a[2347]=0; + a[2348]=0; + a[2349]=0; + a[2350]=0; + a[2351]=0; + a[2352]=0; + a[2353]=0; + a[2354]=0; + a[2355]=0; + a[2356]=0; + a[2357]=0; + a[2358]=0; + a[2359]=0; + a[2360]=0; + a[2361]=0; + a[2362]=0; + a[2363]=0; + a[2364]=0; + a[2365]=0; + a[2366]=0; + a[2367]=0; + a[2368]=0; + a[2369]=0; + a[2370]=0; + a[2371]=0; + a[2372]=0; + a[2373]=0; + a[2374]=0; + a[2375]=0; + a[2376]=0; + a[2377]=0; + a[2378]=0; + a[2379]=0; + a[2380]=0; + a[2381]=0; + a[2382]=0; + a[2383]=0; + a[2384]=0; + a[2385]=0; + a[2386]=0; + a[2387]=0; + a[2388]=0; + a[2389]=0; + a[2390]=0; + a[2391]=0; + a[2392]=0; + a[2393]=0; + a[2394]=0; + a[2395]=0; + a[2396]=0; + a[2397]=0; + a[2398]=0; + a[2399]=0; + a[2400]=0; + a[2401]=0; + a[2402]=0; + a[2403]=0; + a[2404]=0; + a[2405]=0; + a[2406]=0; + a[2407]=0; + a[2408]=0; + a[2409]=0; + a[2410]=0; + a[2411]=0; + a[2412]=0; + a[2413]=0; + a[2414]=0; + a[2415]=0; + a[2416]=0; + a[2417]=0; + a[2418]=0; + a[2419]=0; + a[2420]=0; + a[2421]=0; + a[2422]=0; + a[2423]=0; + a[2424]=0; + a[2425]=0; + a[2426]=0; + a[2427]=0; + a[2428]=0; + a[2429]=0; + a[2430]=0; + a[2431]=0; + a[2432]=0; + a[2433]=0; + a[2434]=0; + a[2435]=0; + a[2436]=0; + a[2437]=0; + a[2438]=0; + a[2439]=0; + a[2440]=0; + a[2441]=0; + a[2442]=0; + a[2443]=0; + a[2444]=0; + a[2445]=0; + a[2446]=0; + a[2447]=0; + a[2448]=0; + a[2449]=0; + a[2450]=0; + a[2451]=0; + a[2452]=0; + a[2453]=0; + a[2454]=0; + a[2455]=0; + a[2456]=0; + a[2457]=0; + a[2458]=0; + a[2459]=0; + a[2460]=0; + a[2461]=0; + a[2462]=0; + a[2463]=0; + a[2464]=0; + a[2465]=0; + a[2466]=0; + a[2467]=0; + a[2468]=0; + a[2469]=0; + a[2470]=0; + a[2471]=0; + a[2472]=0; + a[2473]=0; + a[2474]=0; + a[2475]=0; + a[2476]=0; + a[2477]=0; + a[2478]=0; + a[2479]=0; + a[2480]=0; + a[2481]=0; + a[2482]=0; + a[2483]=0; + a[2484]=0; + a[2485]=0; + a[2486]=0; + a[2487]=0; + a[2488]=0; + a[2489]=0; + a[2490]=0; + a[2491]=0; + a[2492]=0; + a[2493]=0; + a[2494]=0; + a[2495]=0; + a[2496]=0; + a[2497]=0; + a[2498]=0; + a[2499]=0; + a[2500]=0; + a[2501]=0; + a[2502]=0; + a[2503]=0; + a[2504]=0; + a[2505]=0; + a[2506]=0; + a[2507]=0; + a[2508]=0; + a[2509]=0; + a[2510]=0; + a[2511]=0; + a[2512]=0; + a[2513]=0; + a[2514]=0; + a[2515]=0; + a[2516]=0; + a[2517]=0; + a[2518]=0; + a[2519]=0; + a[2520]=0; + a[2521]=0; + a[2522]=0; + a[2523]=0; + a[2524]=0; + a[2525]=0; + a[2526]=0; + a[2527]=0; + a[2528]=0; + a[2529]=0; + a[2530]=0; + a[2531]=0; + a[2532]=0; + a[2533]=0; + a[2534]=0; + a[2535]=0; + a[2536]=0; + a[2537]=0; + a[2538]=0; + a[2539]=0; + a[2540]=0; + a[2541]=0; + a[2542]=0; + a[2543]=0; + a[2544]=0; + a[2545]=0; + a[2546]=0; + a[2547]=0; + a[2548]=0; + a[2549]=0; + a[2550]=0; + a[2551]=0; + a[2552]=0; + a[2553]=0; + a[2554]=0; + a[2555]=0; + a[2556]=0; + a[2557]=0; + a[2558]=0; + a[2559]=0; + a[2560]=0; + a[2561]=0; + a[2562]=0; + a[2563]=0; + a[2564]=0; + a[2565]=0; + a[2566]=0; + a[2567]=0; + a[2568]=0; + a[2569]=0; + a[2570]=0; + a[2571]=0; + a[2572]=0; + a[2573]=0; + a[2574]=0; + a[2575]=0; + a[2576]=0; + a[2577]=0; + a[2578]=0; + a[2579]=0; + a[2580]=0; + a[2581]=0; + a[2582]=0; + a[2583]=0; + a[2584]=0; + a[2585]=0; + a[2586]=0; + a[2587]=0; + a[2588]=0; + a[2589]=0; + a[2590]=0; + a[2591]=0; + a[2592]=0; + a[2593]=0; + a[2594]=0; + a[2595]=0; + a[2596]=0; + a[2597]=0; + a[2598]=0; + a[2599]=0; + a[2600]=0; + a[2601]=0; + a[2602]=0; + a[2603]=0; + a[2604]=0; + a[2605]=0; + a[2606]=0; + a[2607]=0; + a[2608]=0; + a[2609]=0; + a[2610]=0; + a[2611]=0; + a[2612]=0; + a[2613]=0; + a[2614]=0; + a[2615]=0; + a[2616]=0; + a[2617]=0; + a[2618]=0; + a[2619]=0; + a[2620]=0; + a[2621]=0; + a[2622]=0; + a[2623]=0; + a[2624]=0; + a[2625]=0; + a[2626]=0; + a[2627]=0; + a[2628]=0; + a[2629]=0; + a[2630]=0; + a[2631]=0; + a[2632]=0; + a[2633]=0; + a[2634]=0; + a[2635]=0; + a[2636]=0; + a[2637]=0; + a[2638]=0; + a[2639]=0; + a[2640]=0; + a[2641]=0; + a[2642]=0; + a[2643]=0; + a[2644]=0; + a[2645]=0; + a[2646]=0; + a[2647]=0; + a[2648]=0; + a[2649]=0; + a[2650]=0; + a[2651]=0; + a[2652]=0; + a[2653]=0; + a[2654]=0; + a[2655]=0; + a[2656]=0; + a[2657]=0; + a[2658]=0; + a[2659]=0; + a[2660]=0; + a[2661]=0; + a[2662]=0; + a[2663]=0; + a[2664]=0; + a[2665]=0; + a[2666]=0; + a[2667]=0; + a[2668]=0; + a[2669]=0; + a[2670]=0; + a[2671]=0; + a[2672]=0; + a[2673]=0; + a[2674]=0; + a[2675]=0; + a[2676]=0; + a[2677]=0; + a[2678]=0; + a[2679]=0; + a[2680]=0; + a[2681]=0; + a[2682]=0; + a[2683]=0; + a[2684]=0; + a[2685]=0; + a[2686]=0; + a[2687]=0; + a[2688]=0; + a[2689]=0; + a[2690]=0; + a[2691]=0; + a[2692]=0; + a[2693]=0; + a[2694]=0; + a[2695]=0; + a[2696]=0; + a[2697]=0; + a[2698]=0; + a[2699]=0; + a[2700]=0; + a[2701]=0; + a[2702]=0; + a[2703]=0; + a[2704]=0; + a[2705]=0; + a[2706]=0; + a[2707]=0; + a[2708]=0; + a[2709]=0; + a[2710]=0; + a[2711]=0; + a[2712]=0; + a[2713]=0; + a[2714]=0; + a[2715]=0; + a[2716]=0; + a[2717]=0; + a[2718]=0; + a[2719]=0; + a[2720]=0; + a[2721]=0; + a[2722]=0; + a[2723]=0; + a[2724]=0; + a[2725]=0; + a[2726]=0; + a[2727]=0; + a[2728]=0; + a[2729]=0; + a[2730]=0; + a[2731]=0; + a[2732]=0; + a[2733]=0; + a[2734]=0; + a[2735]=0; + a[2736]=0; + a[2737]=0; + a[2738]=0; + a[2739]=0; + a[2740]=0; + a[2741]=0; + a[2742]=0; + a[2743]=0; + a[2744]=0; + a[2745]=0; + a[2746]=0; + a[2747]=0; + a[2748]=0; + a[2749]=0; + a[2750]=0; + a[2751]=0; + a[2752]=0; + a[2753]=0; + a[2754]=0; + a[2755]=0; + a[2756]=0; + a[2757]=0; + a[2758]=0; + a[2759]=0; + a[2760]=0; + a[2761]=0; + a[2762]=0; + a[2763]=0; + a[2764]=0; + a[2765]=0; + a[2766]=0; + a[2767]=0; + a[2768]=0; + a[2769]=0; + a[2770]=0; + a[2771]=0; + a[2772]=0; + a[2773]=0; + a[2774]=0; + a[2775]=0; + a[2776]=0; + a[2777]=0; + a[2778]=0; + a[2779]=0; + a[2780]=0; + a[2781]=0; + a[2782]=0; + a[2783]=0; + a[2784]=0; + a[2785]=0; + a[2786]=0; + a[2787]=0; + a[2788]=0; + a[2789]=0; + a[2790]=0; + a[2791]=0; + a[2792]=0; + a[2793]=0; + a[2794]=0; + a[2795]=0; + a[2796]=0; + a[2797]=0; + a[2798]=0; + a[2799]=0; + a[2800]=0; + a[2801]=0; + a[2802]=0; + a[2803]=0; + a[2804]=0; + a[2805]=0; + a[2806]=0; + a[2807]=0; + a[2808]=0; + a[2809]=0; + a[2810]=0; + a[2811]=0; + a[2812]=0; + a[2813]=0; + a[2814]=0; + a[2815]=0; + a[2816]=0; + a[2817]=0; + a[2818]=0; + a[2819]=0; + a[2820]=0; + a[2821]=0; + a[2822]=0; + a[2823]=0; + a[2824]=0; + a[2825]=0; + a[2826]=0; + a[2827]=0; + a[2828]=0; + a[2829]=0; + a[2830]=0; + a[2831]=0; + a[2832]=0; + a[2833]=0; + a[2834]=0; + a[2835]=0; + a[2836]=0; + a[2837]=0; + a[2838]=0; + a[2839]=0; + a[2840]=0; + a[2841]=0; + a[2842]=0; + a[2843]=0; + a[2844]=0; + a[2845]=0; + a[2846]=0; + a[2847]=0; + a[2848]=0; + a[2849]=0; + a[2850]=0; + a[2851]=0; + a[2852]=0; + a[2853]=0; + a[2854]=0; + a[2855]=0; + a[2856]=0; + a[2857]=0; + a[2858]=0; + a[2859]=0; + a[2860]=0; + a[2861]=0; + a[2862]=0; + a[2863]=0; + a[2864]=0; + a[2865]=0; + a[2866]=0; + a[2867]=0; + a[2868]=0; + a[2869]=0; + a[2870]=0; + a[2871]=0; + a[2872]=0; + a[2873]=0; + a[2874]=0; + a[2875]=0; + a[2876]=0; + a[2877]=0; + a[2878]=0; + a[2879]=0; + a[2880]=0; + a[2881]=0; + a[2882]=0; + a[2883]=0; + a[2884]=0; + a[2885]=0; + a[2886]=0; + a[2887]=0; + a[2888]=0; + a[2889]=0; + a[2890]=0; + a[2891]=0; + a[2892]=0; + a[2893]=0; + a[2894]=0; + a[2895]=0; + a[2896]=0; + a[2897]=0; + a[2898]=0; + a[2899]=0; + a[2900]=0; + a[2901]=0; + a[2902]=0; + a[2903]=0; + a[2904]=0; + a[2905]=0; + a[2906]=0; + a[2907]=0; + a[2908]=0; + a[2909]=0; + a[2910]=0; + a[2911]=0; + a[2912]=0; + a[2913]=0; + a[2914]=0; + a[2915]=0; + a[2916]=0; + a[2917]=0; + a[2918]=0; + a[2919]=0; + a[2920]=0; + a[2921]=0; + a[2922]=0; + a[2923]=0; + a[2924]=0; + a[2925]=0; + a[2926]=0; + a[2927]=0; + a[2928]=0; + a[2929]=0; + a[2930]=0; + a[2931]=0; + a[2932]=0; + a[2933]=0; + a[2934]=0; + a[2935]=0; + a[2936]=0; + a[2937]=0; + a[2938]=0; + a[2939]=0; + a[2940]=0; + a[2941]=0; + a[2942]=0; + a[2943]=0; + a[2944]=0; + a[2945]=0; + a[2946]=0; + a[2947]=0; + a[2948]=0; + a[2949]=0; + a[2950]=0; + a[2951]=0; + a[2952]=0; + a[2953]=0; + a[2954]=0; + a[2955]=0; + a[2956]=0; + a[2957]=0; + a[2958]=0; + a[2959]=0; + a[2960]=0; + a[2961]=0; + a[2962]=0; + a[2963]=0; + a[2964]=0; + a[2965]=0; + a[2966]=0; + a[2967]=0; + a[2968]=0; + a[2969]=0; + a[2970]=0; + a[2971]=0; + a[2972]=0; + a[2973]=0; + a[2974]=0; + a[2975]=0; + a[2976]=0; + a[2977]=0; + a[2978]=0; + a[2979]=0; + a[2980]=0; + a[2981]=0; + a[2982]=0; + a[2983]=0; + a[2984]=0; + a[2985]=0; + a[2986]=0; + a[2987]=0; + a[2988]=0; + a[2989]=0; + a[2990]=0; + a[2991]=0; + a[2992]=0; + a[2993]=0; + a[2994]=0; + a[2995]=0; + a[2996]=0; + a[2997]=0; + a[2998]=0; + a[2999]=0; + a[3000]=0; + a[3001]=0; + a[3002]=0; + a[3003]=0; + a[3004]=0; + a[3005]=0; + a[3006]=0; + a[3007]=0; + a[3008]=0; + a[3009]=0; + a[3010]=0; + a[3011]=0; + a[3012]=0; + a[3013]=0; + a[3014]=0; + a[3015]=0; + a[3016]=0; + a[3017]=0; + a[3018]=0; + a[3019]=0; + a[3020]=0; + a[3021]=0; + a[3022]=0; + a[3023]=0; + a[3024]=0; + a[3025]=0; + a[3026]=0; + a[3027]=0; + a[3028]=0; + a[3029]=0; + a[3030]=0; + a[3031]=0; + a[3032]=0; + a[3033]=0; + a[3034]=0; + a[3035]=0; + a[3036]=0; + a[3037]=0; + a[3038]=0; + a[3039]=0; + a[3040]=0; + a[3041]=0; + a[3042]=0; + a[3043]=0; + a[3044]=0; + a[3045]=0; + a[3046]=0; + a[3047]=0; + a[3048]=0; + a[3049]=0; + a[3050]=0; + a[3051]=0; + a[3052]=0; + a[3053]=0; + a[3054]=0; + a[3055]=0; + a[3056]=0; + a[3057]=0; + a[3058]=0; + a[3059]=0; + a[3060]=0; + a[3061]=0; + a[3062]=0; + a[3063]=0; + a[3064]=0; + a[3065]=0; + a[3066]=0; + a[3067]=0; + a[3068]=0; + a[3069]=0; + a[3070]=0; + a[3071]=0; + a[3072]=0; + a[3073]=0; + a[3074]=0; + a[3075]=0; + a[3076]=0; + a[3077]=0; + a[3078]=0; + a[3079]=0; + a[3080]=0; + a[3081]=0; + a[3082]=0; + a[3083]=0; + a[3084]=0; + a[3085]=0; + a[3086]=0; + a[3087]=0; + a[3088]=0; + a[3089]=0; + a[3090]=0; + a[3091]=0; + a[3092]=0; + a[3093]=0; + a[3094]=0; + a[3095]=0; + a[3096]=0; + a[3097]=0; + a[3098]=0; + a[3099]=0; + a[3100]=0; + a[3101]=0; + a[3102]=0; + a[3103]=0; + a[3104]=0; + a[3105]=0; + a[3106]=0; + a[3107]=0; + a[3108]=0; + a[3109]=0; + a[3110]=0; + a[3111]=0; + a[3112]=0; + a[3113]=0; + a[3114]=0; + a[3115]=0; + a[3116]=0; + a[3117]=0; + a[3118]=0; + a[3119]=0; + a[3120]=0; + a[3121]=0; + a[3122]=0; + a[3123]=0; + a[3124]=0; + a[3125]=0; + a[3126]=0; + a[3127]=0; + a[3128]=0; + a[3129]=0; + a[3130]=0; + a[3131]=0; + a[3132]=0; + a[3133]=0; + a[3134]=0; + a[3135]=0; + a[3136]=0; + a[3137]=0; + a[3138]=0; + a[3139]=0; + a[3140]=0; + a[3141]=0; + a[3142]=0; + a[3143]=0; + a[3144]=0; + a[3145]=0; + a[3146]=0; + a[3147]=0; + a[3148]=0; + a[3149]=0; + a[3150]=0; + a[3151]=0; + a[3152]=0; + a[3153]=0; + a[3154]=0; + a[3155]=0; + a[3156]=0; + a[3157]=0; + a[3158]=0; + a[3159]=0; + a[3160]=0; + a[3161]=0; + a[3162]=0; + a[3163]=0; + a[3164]=0; + a[3165]=0; + a[3166]=0; + a[3167]=0; + a[3168]=0; + a[3169]=0; + a[3170]=0; + a[3171]=0; + a[3172]=0; + a[3173]=0; + a[3174]=0; + a[3175]=0; + a[3176]=0; + a[3177]=0; + a[3178]=0; + a[3179]=0; + a[3180]=0; + a[3181]=0; + a[3182]=0; + a[3183]=0; + a[3184]=0; + a[3185]=0; + a[3186]=0; + a[3187]=0; + a[3188]=0; + a[3189]=0; + a[3190]=0; + a[3191]=0; + a[3192]=0; + a[3193]=0; + a[3194]=0; + a[3195]=0; + a[3196]=0; + a[3197]=0; + a[3198]=0; + a[3199]=0; + a[3200]=0; + a[3201]=0; + a[3202]=0; + a[3203]=0; + a[3204]=0; + a[3205]=0; + a[3206]=0; + a[3207]=0; + a[3208]=0; + a[3209]=0; + a[3210]=0; + a[3211]=0; + a[3212]=0; + a[3213]=0; + a[3214]=0; + a[3215]=0; + a[3216]=0; + a[3217]=0; + a[3218]=0; + a[3219]=0; + a[3220]=0; + a[3221]=0; + a[3222]=0; + a[3223]=0; + a[3224]=0; + a[3225]=0; + a[3226]=0; + a[3227]=0; + a[3228]=0; + a[3229]=0; + a[3230]=0; + a[3231]=0; + a[3232]=0; + a[3233]=0; + a[3234]=0; + a[3235]=0; + a[3236]=0; + a[3237]=0; + a[3238]=0; + a[3239]=0; + a[3240]=0; + a[3241]=0; + a[3242]=0; + a[3243]=0; + a[3244]=0; + a[3245]=0; + a[3246]=0; + a[3247]=0; + a[3248]=0; + a[3249]=0; + a[3250]=0; + a[3251]=0; + a[3252]=0; + a[3253]=0; + a[3254]=0; + a[3255]=0; + a[3256]=0; + a[3257]=0; + a[3258]=0; + a[3259]=0; + a[3260]=0; + a[3261]=0; + a[3262]=0; + a[3263]=0; + a[3264]=0; + a[3265]=0; + a[3266]=0; + a[3267]=0; + a[3268]=0; + a[3269]=0; + a[3270]=0; + a[3271]=0; + a[3272]=0; + a[3273]=0; + a[3274]=0; + a[3275]=0; + a[3276]=0; + a[3277]=0; + a[3278]=0; + a[3279]=0; + a[3280]=0; + a[3281]=0; + a[3282]=0; + a[3283]=0; + a[3284]=0; + a[3285]=0; + a[3286]=0; + a[3287]=0; + a[3288]=0; + a[3289]=0; + a[3290]=0; + a[3291]=0; + a[3292]=0; + a[3293]=0; + a[3294]=0; + a[3295]=0; + a[3296]=0; + a[3297]=0; + a[3298]=0; + a[3299]=0; + a[3300]=0; + a[3301]=0; + a[3302]=0; + a[3303]=0; + a[3304]=0; + a[3305]=0; + a[3306]=0; + a[3307]=0; + a[3308]=0; + a[3309]=0; + a[3310]=0; + a[3311]=0; + a[3312]=0; + a[3313]=0; + a[3314]=0; + a[3315]=0; + a[3316]=0; + a[3317]=0; + a[3318]=0; + a[3319]=0; + a[3320]=0; + a[3321]=0; + a[3322]=0; + a[3323]=0; + a[3324]=0; + a[3325]=0; + a[3326]=0; + a[3327]=0; + a[3328]=0; + a[3329]=0; + a[3330]=0; + a[3331]=0; + a[3332]=0; + a[3333]=0; + a[3334]=0; + a[3335]=0; + a[3336]=0; + a[3337]=0; + a[3338]=0; + a[3339]=0; + a[3340]=0; + a[3341]=0; + a[3342]=0; + a[3343]=0; + a[3344]=0; + a[3345]=0; + a[3346]=0; + a[3347]=0; + a[3348]=0; + a[3349]=0; + a[3350]=0; + a[3351]=0; + a[3352]=0; + a[3353]=0; + a[3354]=0; + a[3355]=0; + a[3356]=0; + a[3357]=0; + a[3358]=0; + a[3359]=0; + a[3360]=0; + a[3361]=0; + a[3362]=0; + a[3363]=0; + a[3364]=0; + a[3365]=0; + a[3366]=0; + a[3367]=0; + a[3368]=0; + a[3369]=0; + a[3370]=0; + a[3371]=0; + a[3372]=0; + a[3373]=0; + a[3374]=0; + a[3375]=0; + a[3376]=0; + a[3377]=0; + a[3378]=0; + a[3379]=0; + a[3380]=0; + a[3381]=0; + a[3382]=0; + a[3383]=0; + a[3384]=0; + a[3385]=0; + a[3386]=0; + a[3387]=0; + a[3388]=0; + a[3389]=0; + a[3390]=0; + a[3391]=0; + a[3392]=0; + a[3393]=0; + a[3394]=0; + a[3395]=0; + a[3396]=0; + a[3397]=0; + a[3398]=0; + a[3399]=0; + a[3400]=0; + a[3401]=0; + a[3402]=0; + a[3403]=0; + a[3404]=0; + a[3405]=0; + a[3406]=0; + a[3407]=0; + a[3408]=0; + a[3409]=0; + a[3410]=0; + a[3411]=0; + a[3412]=0; + a[3413]=0; + a[3414]=0; + a[3415]=0; + a[3416]=0; + a[3417]=0; + a[3418]=0; + a[3419]=0; + a[3420]=0; + a[3421]=0; + a[3422]=0; + a[3423]=0; + a[3424]=0; + a[3425]=0; + a[3426]=0; + a[3427]=0; + a[3428]=0; + a[3429]=0; + a[3430]=0; + a[3431]=0; + a[3432]=0; + a[3433]=0; + a[3434]=0; + a[3435]=0; + a[3436]=0; + a[3437]=0; + a[3438]=0; + a[3439]=0; + a[3440]=0; + a[3441]=0; + a[3442]=0; + a[3443]=0; + a[3444]=0; + a[3445]=0; + a[3446]=0; + a[3447]=0; + a[3448]=0; + a[3449]=0; + a[3450]=0; + a[3451]=0; + a[3452]=0; + a[3453]=0; + a[3454]=0; + a[3455]=0; + a[3456]=0; + a[3457]=0; + a[3458]=0; + a[3459]=0; + a[3460]=0; + a[3461]=0; + a[3462]=0; + a[3463]=0; + a[3464]=0; + a[3465]=0; + a[3466]=0; + a[3467]=0; + a[3468]=0; + a[3469]=0; + a[3470]=0; + a[3471]=0; + a[3472]=0; + a[3473]=0; + a[3474]=0; + a[3475]=0; + a[3476]=0; + a[3477]=0; + a[3478]=0; + a[3479]=0; + a[3480]=0; + a[3481]=0; + a[3482]=0; + a[3483]=0; + a[3484]=0; + a[3485]=0; + a[3486]=0; + a[3487]=0; + a[3488]=0; + a[3489]=0; + a[3490]=0; + a[3491]=0; + a[3492]=0; + a[3493]=0; + a[3494]=0; + a[3495]=0; + a[3496]=0; + a[3497]=0; + a[3498]=0; + a[3499]=0; + a[3500]=0; + a[3501]=0; + a[3502]=0; + a[3503]=0; + a[3504]=0; + a[3505]=0; + a[3506]=0; + a[3507]=0; + a[3508]=0; + a[3509]=0; + a[3510]=0; + a[3511]=0; + a[3512]=0; + a[3513]=0; + a[3514]=0; + a[3515]=0; + a[3516]=0; + a[3517]=0; + a[3518]=0; + a[3519]=0; + a[3520]=0; + a[3521]=0; + a[3522]=0; + a[3523]=0; + a[3524]=0; + a[3525]=0; + a[3526]=0; + a[3527]=0; + a[3528]=0; + a[3529]=0; + a[3530]=0; + a[3531]=0; + a[3532]=0; + a[3533]=0; + a[3534]=0; + a[3535]=0; + a[3536]=0; + a[3537]=0; + a[3538]=0; + a[3539]=0; + a[3540]=0; + a[3541]=0; + a[3542]=0; + a[3543]=0; + a[3544]=0; + a[3545]=0; + a[3546]=0; + a[3547]=0; + a[3548]=0; + a[3549]=0; + a[3550]=0; + a[3551]=0; + a[3552]=0; + a[3553]=0; + a[3554]=0; + a[3555]=0; + a[3556]=0; + a[3557]=0; + a[3558]=0; + a[3559]=0; + a[3560]=0; + a[3561]=0; + a[3562]=0; + a[3563]=0; + a[3564]=0; + a[3565]=0; + a[3566]=0; + a[3567]=0; + a[3568]=0; + a[3569]=0; + a[3570]=0; + a[3571]=0; + a[3572]=0; + a[3573]=0; + a[3574]=0; + a[3575]=0; + a[3576]=0; + a[3577]=0; + a[3578]=0; + a[3579]=0; + a[3580]=0; + a[3581]=0; + a[3582]=0; + a[3583]=0; + a[3584]=0; + a[3585]=0; + a[3586]=0; + a[3587]=0; + a[3588]=0; + a[3589]=0; + a[3590]=0; + a[3591]=0; + a[3592]=0; + a[3593]=0; + a[3594]=0; + a[3595]=0; + a[3596]=0; + a[3597]=0; + a[3598]=0; + a[3599]=0; + a[3600]=0; + a[3601]=0; + a[3602]=0; + a[3603]=0; + a[3604]=0; + a[3605]=0; + a[3606]=0; + a[3607]=0; + a[3608]=0; + a[3609]=0; + a[3610]=0; + a[3611]=0; + a[3612]=0; + a[3613]=0; + a[3614]=0; + a[3615]=0; + a[3616]=0; + a[3617]=0; + a[3618]=0; + a[3619]=0; + a[3620]=0; + a[3621]=0; + a[3622]=0; + a[3623]=0; + a[3624]=0; + a[3625]=0; + a[3626]=0; + a[3627]=0; + a[3628]=0; + a[3629]=0; + a[3630]=0; + a[3631]=0; + a[3632]=0; + a[3633]=0; + a[3634]=0; + a[3635]=0; + a[3636]=0; + a[3637]=0; + a[3638]=0; + a[3639]=0; + a[3640]=0; + a[3641]=0; + a[3642]=0; + a[3643]=0; + a[3644]=0; + a[3645]=0; + a[3646]=0; + a[3647]=0; + a[3648]=0; + a[3649]=0; + a[3650]=0; + a[3651]=0; + a[3652]=0; + a[3653]=0; + a[3654]=0; + a[3655]=0; + a[3656]=0; + a[3657]=0; + a[3658]=0; + a[3659]=0; + a[3660]=0; + a[3661]=0; + a[3662]=0; + a[3663]=0; + a[3664]=0; + a[3665]=0; + a[3666]=0; + a[3667]=0; + a[3668]=0; + a[3669]=0; + a[3670]=0; + a[3671]=0; + a[3672]=0; + a[3673]=0; + a[3674]=0; + a[3675]=0; + a[3676]=0; + a[3677]=0; + a[3678]=0; + a[3679]=0; + a[3680]=0; + a[3681]=0; + a[3682]=0; + a[3683]=0; + a[3684]=0; + a[3685]=0; + a[3686]=0; + a[3687]=0; + a[3688]=0; + a[3689]=0; + a[3690]=0; + a[3691]=0; + a[3692]=0; + a[3693]=0; + a[3694]=0; + a[3695]=0; + a[3696]=0; + a[3697]=0; + a[3698]=0; + a[3699]=0; + a[3700]=0; + a[3701]=0; + a[3702]=0; + a[3703]=0; + a[3704]=0; + a[3705]=0; + a[3706]=0; + a[3707]=0; + a[3708]=0; + a[3709]=0; + a[3710]=0; + a[3711]=0; + a[3712]=0; + a[3713]=0; + a[3714]=0; + a[3715]=0; + a[3716]=0; + a[3717]=0; + a[3718]=0; + a[3719]=0; + a[3720]=0; + a[3721]=0; + a[3722]=0; + a[3723]=0; + a[3724]=0; + a[3725]=0; + a[3726]=0; + a[3727]=0; + a[3728]=0; + a[3729]=0; + a[3730]=0; + a[3731]=0; + a[3732]=0; + a[3733]=0; + a[3734]=0; + a[3735]=0; + a[3736]=0; + a[3737]=0; + a[3738]=0; + a[3739]=0; + a[3740]=0; + a[3741]=0; + a[3742]=0; + a[3743]=0; + a[3744]=0; + a[3745]=0; + a[3746]=0; + a[3747]=0; + a[3748]=0; + a[3749]=0; + a[3750]=0; + a[3751]=0; + a[3752]=0; + a[3753]=0; + a[3754]=0; + a[3755]=0; + a[3756]=0; + a[3757]=0; + a[3758]=0; + a[3759]=0; + a[3760]=0; + a[3761]=0; + a[3762]=0; + a[3763]=0; + a[3764]=0; + a[3765]=0; + a[3766]=0; + a[3767]=0; + a[3768]=0; + a[3769]=0; + a[3770]=0; + a[3771]=0; + a[3772]=0; + a[3773]=0; + a[3774]=0; + a[3775]=0; + a[3776]=0; + a[3777]=0; + a[3778]=0; + a[3779]=0; + a[3780]=0; + a[3781]=0; + a[3782]=0; + a[3783]=0; + a[3784]=0; + a[3785]=0; + a[3786]=0; + a[3787]=0; + a[3788]=0; + a[3789]=0; + a[3790]=0; + a[3791]=0; + a[3792]=0; + a[3793]=0; + a[3794]=0; + a[3795]=0; + a[3796]=0; + a[3797]=0; + a[3798]=0; + a[3799]=0; + a[3800]=0; + a[3801]=0; + a[3802]=0; + a[3803]=0; + a[3804]=0; + a[3805]=0; + a[3806]=0; + a[3807]=0; + a[3808]=0; + a[3809]=0; + a[3810]=0; + a[3811]=0; + a[3812]=0; + a[3813]=0; + a[3814]=0; + a[3815]=0; + a[3816]=0; + a[3817]=0; + a[3818]=0; + a[3819]=0; + a[3820]=0; + a[3821]=0; + a[3822]=0; + a[3823]=0; + a[3824]=0; + a[3825]=0; + a[3826]=0; + a[3827]=0; + a[3828]=0; + a[3829]=0; + a[3830]=0; + a[3831]=0; + a[3832]=0; + a[3833]=0; + a[3834]=0; + a[3835]=0; + a[3836]=0; + a[3837]=0; + a[3838]=0; + a[3839]=0; + a[3840]=0; + a[3841]=0; + a[3842]=0; + a[3843]=0; + a[3844]=0; + a[3845]=0; + a[3846]=0; + a[3847]=0; + a[3848]=0; + a[3849]=0; + a[3850]=0; + a[3851]=0; + a[3852]=0; + a[3853]=0; + a[3854]=0; + a[3855]=0; + a[3856]=0; + a[3857]=0; + a[3858]=0; + a[3859]=0; + a[3860]=0; + a[3861]=0; + a[3862]=0; + a[3863]=0; + a[3864]=0; + a[3865]=0; + a[3866]=0; + a[3867]=0; + a[3868]=0; + a[3869]=0; + a[3870]=0; + a[3871]=0; + a[3872]=0; + a[3873]=0; + a[3874]=0; + a[3875]=0; + a[3876]=0; + a[3877]=0; + a[3878]=0; + a[3879]=0; + a[3880]=0; + a[3881]=0; + a[3882]=0; + a[3883]=0; + a[3884]=0; + a[3885]=0; + a[3886]=0; + a[3887]=0; + a[3888]=0; + a[3889]=0; + a[3890]=0; + a[3891]=0; + a[3892]=0; + a[3893]=0; + a[3894]=0; + a[3895]=0; + a[3896]=0; + a[3897]=0; + a[3898]=0; + a[3899]=0; + a[3900]=0; + a[3901]=0; + a[3902]=0; + a[3903]=0; + a[3904]=0; + a[3905]=0; + a[3906]=0; + a[3907]=0; + a[3908]=0; + a[3909]=0; + a[3910]=0; + a[3911]=0; + a[3912]=0; + a[3913]=0; + a[3914]=0; + a[3915]=0; + a[3916]=0; + a[3917]=0; + a[3918]=0; + a[3919]=0; + a[3920]=0; + a[3921]=0; + a[3922]=0; + a[3923]=0; + a[3924]=0; + a[3925]=0; + a[3926]=0; + a[3927]=0; + a[3928]=0; + a[3929]=0; + a[3930]=0; + a[3931]=0; + a[3932]=0; + a[3933]=0; + a[3934]=0; + a[3935]=0; + a[3936]=0; + a[3937]=0; + a[3938]=0; + a[3939]=0; + a[3940]=0; + a[3941]=0; + a[3942]=0; + a[3943]=0; + a[3944]=0; + a[3945]=0; + a[3946]=0; + a[3947]=0; + a[3948]=0; + a[3949]=0; + a[3950]=0; + a[3951]=0; + a[3952]=0; + a[3953]=0; + a[3954]=0; + a[3955]=0; + a[3956]=0; + a[3957]=0; + a[3958]=0; + a[3959]=0; + a[3960]=0; + a[3961]=0; + a[3962]=0; + a[3963]=0; + a[3964]=0; + a[3965]=0; + a[3966]=0; + a[3967]=0; + a[3968]=0; + a[3969]=0; + a[3970]=0; + a[3971]=0; + a[3972]=0; + a[3973]=0; + a[3974]=0; + a[3975]=0; + a[3976]=0; + a[3977]=0; + a[3978]=0; + a[3979]=0; + a[3980]=0; + a[3981]=0; + a[3982]=0; + a[3983]=0; + a[3984]=0; + a[3985]=0; + a[3986]=0; + a[3987]=0; + a[3988]=0; + a[3989]=0; + a[3990]=0; + a[3991]=0; + a[3992]=0; + a[3993]=0; + a[3994]=0; + a[3995]=0; + a[3996]=0; + a[3997]=0; + a[3998]=0; + a[3999]=0; + a[4000]=0; + a[4001]=0; + a[4002]=0; + a[4003]=0; + a[4004]=0; + a[4005]=0; + a[4006]=0; + a[4007]=0; + a[4008]=0; + a[4009]=0; + a[4010]=0; + a[4011]=0; + a[4012]=0; + a[4013]=0; + a[4014]=0; + a[4015]=0; + a[4016]=0; + a[4017]=0; + a[4018]=0; + a[4019]=0; + a[4020]=0; + a[4021]=0; + a[4022]=0; + a[4023]=0; + a[4024]=0; + a[4025]=0; + a[4026]=0; + a[4027]=0; + a[4028]=0; + a[4029]=0; + a[4030]=0; + a[4031]=0; + a[4032]=0; + a[4033]=0; + a[4034]=0; + a[4035]=0; + a[4036]=0; + a[4037]=0; + a[4038]=0; + a[4039]=0; + a[4040]=0; + a[4041]=0; + a[4042]=0; + a[4043]=0; + a[4044]=0; + a[4045]=0; + a[4046]=0; + a[4047]=0; + a[4048]=0; + a[4049]=0; + a[4050]=0; + a[4051]=0; + a[4052]=0; + a[4053]=0; + a[4054]=0; + a[4055]=0; + a[4056]=0; + a[4057]=0; + a[4058]=0; + a[4059]=0; + a[4060]=0; + a[4061]=0; + a[4062]=0; + a[4063]=0; + a[4064]=0; + a[4065]=0; + a[4066]=0; + a[4067]=0; + a[4068]=0; + a[4069]=0; + a[4070]=0; + a[4071]=0; + a[4072]=0; + a[4073]=0; + a[4074]=0; + a[4075]=0; + a[4076]=0; + a[4077]=0; + a[4078]=0; + a[4079]=0; + a[4080]=0; + a[4081]=0; + a[4082]=0; + a[4083]=0; + a[4084]=0; + a[4085]=0; + a[4086]=0; + a[4087]=0; + a[4088]=0; + a[4089]=0; + a[4090]=0; + a[4091]=0; + a[4092]=0; + a[4093]=0; + a[4094]=0; + a[4095]=0; + a[4096]=0; + a[4097]=0; + a[4098]=0; + a[4099]=0; + a[4100]=0; + a[4101]=0; + a[4102]=0; + a[4103]=0; + a[4104]=0; + a[4105]=0; + a[4106]=0; + a[4107]=0; + a[4108]=0; + a[4109]=0; + a[4110]=0; + a[4111]=0; + a[4112]=0; + a[4113]=0; + a[4114]=0; + a[4115]=0; + a[4116]=0; + a[4117]=0; + a[4118]=0; + a[4119]=0; + a[4120]=0; + a[4121]=0; + a[4122]=0; + a[4123]=0; + a[4124]=0; + a[4125]=0; + a[4126]=0; + a[4127]=0; + a[4128]=0; + a[4129]=0; + a[4130]=0; + a[4131]=0; + a[4132]=0; + a[4133]=0; + a[4134]=0; + a[4135]=0; + a[4136]=0; + a[4137]=0; + a[4138]=0; + a[4139]=0; + a[4140]=0; + a[4141]=0; + a[4142]=0; + a[4143]=0; + a[4144]=0; + a[4145]=0; + a[4146]=0; + a[4147]=0; + a[4148]=0; + a[4149]=0; + a[4150]=0; + a[4151]=0; + a[4152]=0; + a[4153]=0; + a[4154]=0; + a[4155]=0; + a[4156]=0; + a[4157]=0; + a[4158]=0; + a[4159]=0; + a[4160]=0; + a[4161]=0; + a[4162]=0; + a[4163]=0; + a[4164]=0; + a[4165]=0; + a[4166]=0; + a[4167]=0; + a[4168]=0; + a[4169]=0; + a[4170]=0; + a[4171]=0; + a[4172]=0; + a[4173]=0; + a[4174]=0; + a[4175]=0; + a[4176]=0; + a[4177]=0; + a[4178]=0; + a[4179]=0; + a[4180]=0; + a[4181]=0; + a[4182]=0; + a[4183]=0; + a[4184]=0; + a[4185]=0; + a[4186]=0; + a[4187]=0; + a[4188]=0; + a[4189]=0; + a[4190]=0; + a[4191]=0; + a[4192]=0; + a[4193]=0; + a[4194]=0; + a[4195]=0; + a[4196]=0; + a[4197]=0; + a[4198]=0; + a[4199]=0; + a[4200]=0; + a[4201]=0; + a[4202]=0; + a[4203]=0; + a[4204]=0; + a[4205]=0; + a[4206]=0; + a[4207]=0; + a[4208]=0; + a[4209]=0; + a[4210]=0; + a[4211]=0; + a[4212]=0; + a[4213]=0; + a[4214]=0; + a[4215]=0; + a[4216]=0; + a[4217]=0; + a[4218]=0; + a[4219]=0; + a[4220]=0; + a[4221]=0; + a[4222]=0; + a[4223]=0; + a[4224]=0; + a[4225]=0; + a[4226]=0; + a[4227]=0; + a[4228]=0; + a[4229]=0; + a[4230]=0; + a[4231]=0; + a[4232]=0; + a[4233]=0; + a[4234]=0; + a[4235]=0; + a[4236]=0; + a[4237]=0; + a[4238]=0; + a[4239]=0; + a[4240]=0; + a[4241]=0; + a[4242]=0; + a[4243]=0; + a[4244]=0; + a[4245]=0; + a[4246]=0; + a[4247]=0; + a[4248]=0; + a[4249]=0; + a[4250]=0; + a[4251]=0; + a[4252]=0; + a[4253]=0; + a[4254]=0; + a[4255]=0; + a[4256]=0; + a[4257]=0; + a[4258]=0; + a[4259]=0; + a[4260]=0; + a[4261]=0; + a[4262]=0; + a[4263]=0; + a[4264]=0; + a[4265]=0; + a[4266]=0; + a[4267]=0; + a[4268]=0; + a[4269]=0; + a[4270]=0; + a[4271]=0; + a[4272]=0; + a[4273]=0; + a[4274]=0; + a[4275]=0; + a[4276]=0; + a[4277]=0; + a[4278]=0; + a[4279]=0; + a[4280]=0; + a[4281]=0; + a[4282]=0; + a[4283]=0; + a[4284]=0; + a[4285]=0; + a[4286]=0; + a[4287]=0; + a[4288]=0; + a[4289]=0; + a[4290]=0; + a[4291]=0; + a[4292]=0; + a[4293]=0; + a[4294]=0; + a[4295]=0; + a[4296]=0; + a[4297]=0; + a[4298]=0; + a[4299]=0; + a[4300]=0; + a[4301]=0; + a[4302]=0; + a[4303]=0; + a[4304]=0; + a[4305]=0; + a[4306]=0; + a[4307]=0; + a[4308]=0; + a[4309]=0; + a[4310]=0; + a[4311]=0; + a[4312]=0; + a[4313]=0; + a[4314]=0; + a[4315]=0; + a[4316]=0; + a[4317]=0; + a[4318]=0; + a[4319]=0; + a[4320]=0; + a[4321]=0; + a[4322]=0; + a[4323]=0; + a[4324]=0; + a[4325]=0; + a[4326]=0; + a[4327]=0; + a[4328]=0; + a[4329]=0; + a[4330]=0; + a[4331]=0; + a[4332]=0; + a[4333]=0; + a[4334]=0; + a[4335]=0; + a[4336]=0; + a[4337]=0; + a[4338]=0; + a[4339]=0; + a[4340]=0; + a[4341]=0; + a[4342]=0; + a[4343]=0; + a[4344]=0; + a[4345]=0; + a[4346]=0; + a[4347]=0; + a[4348]=0; + a[4349]=0; + a[4350]=0; + a[4351]=0; + a[4352]=0; + a[4353]=0; + a[4354]=0; + a[4355]=0; + a[4356]=0; + a[4357]=0; + a[4358]=0; + a[4359]=0; + a[4360]=0; + a[4361]=0; + a[4362]=0; + a[4363]=0; + a[4364]=0; + a[4365]=0; + a[4366]=0; + a[4367]=0; + a[4368]=0; + a[4369]=0; + a[4370]=0; + a[4371]=0; + a[4372]=0; + a[4373]=0; + a[4374]=0; + a[4375]=0; + a[4376]=0; + a[4377]=0; + a[4378]=0; + a[4379]=0; + a[4380]=0; + a[4381]=0; + a[4382]=0; + a[4383]=0; + a[4384]=0; + a[4385]=0; + a[4386]=0; + a[4387]=0; + a[4388]=0; + a[4389]=0; + a[4390]=0; + a[4391]=0; + a[4392]=0; + a[4393]=0; + a[4394]=0; + a[4395]=0; + a[4396]=0; + a[4397]=0; + a[4398]=0; + a[4399]=0; + a[4400]=0; + a[4401]=0; + a[4402]=0; + a[4403]=0; + a[4404]=0; + a[4405]=0; + a[4406]=0; + a[4407]=0; + a[4408]=0; + a[4409]=0; + a[4410]=0; + a[4411]=0; + a[4412]=0; + a[4413]=0; + a[4414]=0; + a[4415]=0; + a[4416]=0; + a[4417]=0; + a[4418]=0; + a[4419]=0; + a[4420]=0; + a[4421]=0; + a[4422]=0; + a[4423]=0; + a[4424]=0; + a[4425]=0; + a[4426]=0; + a[4427]=0; + a[4428]=0; + a[4429]=0; + a[4430]=0; + a[4431]=0; + a[4432]=0; + a[4433]=0; + a[4434]=0; + a[4435]=0; + a[4436]=0; + a[4437]=0; + a[4438]=0; + a[4439]=0; + a[4440]=0; + a[4441]=0; + a[4442]=0; + a[4443]=0; + a[4444]=0; + a[4445]=0; + a[4446]=0; + a[4447]=0; + a[4448]=0; + a[4449]=0; + a[4450]=0; + a[4451]=0; + a[4452]=0; + a[4453]=0; + a[4454]=0; + a[4455]=0; + a[4456]=0; + a[4457]=0; + a[4458]=0; + a[4459]=0; + a[4460]=0; + a[4461]=0; + a[4462]=0; + a[4463]=0; + a[4464]=0; + a[4465]=0; + a[4466]=0; + a[4467]=0; + a[4468]=0; + a[4469]=0; + a[4470]=0; + a[4471]=0; + a[4472]=0; + a[4473]=0; + a[4474]=0; + a[4475]=0; + a[4476]=0; + a[4477]=0; + a[4478]=0; + a[4479]=0; + a[4480]=0; + a[4481]=0; + a[4482]=0; + a[4483]=0; + a[4484]=0; + a[4485]=0; + a[4486]=0; + a[4487]=0; + a[4488]=0; + a[4489]=0; + a[4490]=0; + a[4491]=0; + a[4492]=0; + a[4493]=0; + a[4494]=0; + a[4495]=0; + a[4496]=0; + a[4497]=0; + a[4498]=0; + a[4499]=0; + a[4500]=0; + a[4501]=0; + a[4502]=0; + a[4503]=0; + a[4504]=0; + a[4505]=0; + a[4506]=0; + a[4507]=0; + a[4508]=0; + a[4509]=0; + a[4510]=0; + a[4511]=0; + a[4512]=0; + a[4513]=0; + a[4514]=0; + a[4515]=0; + a[4516]=0; + a[4517]=0; + a[4518]=0; + a[4519]=0; + a[4520]=0; + a[4521]=0; + a[4522]=0; + a[4523]=0; + a[4524]=0; + a[4525]=0; + a[4526]=0; + a[4527]=0; + a[4528]=0; + a[4529]=0; + a[4530]=0; + a[4531]=0; + a[4532]=0; + a[4533]=0; + a[4534]=0; + a[4535]=0; + a[4536]=0; + a[4537]=0; + a[4538]=0; + a[4539]=0; + a[4540]=0; + a[4541]=0; + a[4542]=0; + a[4543]=0; + a[4544]=0; + a[4545]=0; + a[4546]=0; + a[4547]=0; + a[4548]=0; + a[4549]=0; + a[4550]=0; + a[4551]=0; + a[4552]=0; + a[4553]=0; + a[4554]=0; + a[4555]=0; + a[4556]=0; + a[4557]=0; + a[4558]=0; + a[4559]=0; + a[4560]=0; + a[4561]=0; + a[4562]=0; + a[4563]=0; + a[4564]=0; + a[4565]=0; + a[4566]=0; + a[4567]=0; + a[4568]=0; + a[4569]=0; + a[4570]=0; + a[4571]=0; + a[4572]=0; + a[4573]=0; + a[4574]=0; + a[4575]=0; + a[4576]=0; + a[4577]=0; + a[4578]=0; + a[4579]=0; + a[4580]=0; + a[4581]=0; + a[4582]=0; + a[4583]=0; + a[4584]=0; + a[4585]=0; + a[4586]=0; + a[4587]=0; + a[4588]=0; + a[4589]=0; + a[4590]=0; + a[4591]=0; + a[4592]=0; + a[4593]=0; + a[4594]=0; + a[4595]=0; + a[4596]=0; + a[4597]=0; + a[4598]=0; + a[4599]=0; + a[4600]=0; + a[4601]=0; + a[4602]=0; + a[4603]=0; + a[4604]=0; + a[4605]=0; + a[4606]=0; + a[4607]=0; + a[4608]=0; + a[4609]=0; + a[4610]=0; + a[4611]=0; + a[4612]=0; + a[4613]=0; + a[4614]=0; + a[4615]=0; + a[4616]=0; + a[4617]=0; + a[4618]=0; + a[4619]=0; + a[4620]=0; + a[4621]=0; + a[4622]=0; + a[4623]=0; + a[4624]=0; + a[4625]=0; + a[4626]=0; + a[4627]=0; + a[4628]=0; + a[4629]=0; + a[4630]=0; + a[4631]=0; + a[4632]=0; + a[4633]=0; + a[4634]=0; + a[4635]=0; + a[4636]=0; + a[4637]=0; + a[4638]=0; + a[4639]=0; + a[4640]=0; + a[4641]=0; + a[4642]=0; + a[4643]=0; + a[4644]=0; + a[4645]=0; + a[4646]=0; + a[4647]=0; + a[4648]=0; + a[4649]=0; + a[4650]=0; + a[4651]=0; + a[4652]=0; + a[4653]=0; + a[4654]=0; + a[4655]=0; + a[4656]=0; + a[4657]=0; + a[4658]=0; + a[4659]=0; + a[4660]=0; + a[4661]=0; + a[4662]=0; + a[4663]=0; + a[4664]=0; + a[4665]=0; + a[4666]=0; + a[4667]=0; + a[4668]=0; + a[4669]=0; + a[4670]=0; + a[4671]=0; + a[4672]=0; + a[4673]=0; + a[4674]=0; + a[4675]=0; + a[4676]=0; + a[4677]=0; + a[4678]=0; + a[4679]=0; + a[4680]=0; + a[4681]=0; + a[4682]=0; + a[4683]=0; + a[4684]=0; + a[4685]=0; + a[4686]=0; + a[4687]=0; + a[4688]=0; + a[4689]=0; + a[4690]=0; + a[4691]=0; + a[4692]=0; + a[4693]=0; + a[4694]=0; + a[4695]=0; + a[4696]=0; + a[4697]=0; + a[4698]=0; + a[4699]=0; + a[4700]=0; + a[4701]=0; + a[4702]=0; + a[4703]=0; + a[4704]=0; + a[4705]=0; + a[4706]=0; + a[4707]=0; + a[4708]=0; + a[4709]=0; + a[4710]=0; + a[4711]=0; + a[4712]=0; + a[4713]=0; + a[4714]=0; + a[4715]=0; + a[4716]=0; + a[4717]=0; + a[4718]=0; + a[4719]=0; + a[4720]=0; + a[4721]=0; + a[4722]=0; + a[4723]=0; + a[4724]=0; + a[4725]=0; + a[4726]=0; + a[4727]=0; + a[4728]=0; + a[4729]=0; + a[4730]=0; + a[4731]=0; + a[4732]=0; + a[4733]=0; + a[4734]=0; + a[4735]=0; + a[4736]=0; + a[4737]=0; + a[4738]=0; + a[4739]=0; + a[4740]=0; + a[4741]=0; + a[4742]=0; + a[4743]=0; + a[4744]=0; + a[4745]=0; + a[4746]=0; + a[4747]=0; + a[4748]=0; + a[4749]=0; + a[4750]=0; + a[4751]=0; + a[4752]=0; + a[4753]=0; + a[4754]=0; + a[4755]=0; + a[4756]=0; + a[4757]=0; + a[4758]=0; + a[4759]=0; + a[4760]=0; + a[4761]=0; + a[4762]=0; + a[4763]=0; + a[4764]=0; + a[4765]=0; + a[4766]=0; + a[4767]=0; + a[4768]=0; + a[4769]=0; + a[4770]=0; + a[4771]=0; + a[4772]=0; + a[4773]=0; + a[4774]=0; + a[4775]=0; + a[4776]=0; + a[4777]=0; + a[4778]=0; + a[4779]=0; + a[4780]=0; + a[4781]=0; + a[4782]=0; + a[4783]=0; + a[4784]=0; + a[4785]=0; + a[4786]=0; + a[4787]=0; + a[4788]=0; + a[4789]=0; + a[4790]=0; + a[4791]=0; + a[4792]=0; + a[4793]=0; + a[4794]=0; + a[4795]=0; + a[4796]=0; + a[4797]=0; + a[4798]=0; + a[4799]=0; + a[4800]=0; + a[4801]=0; + a[4802]=0; + a[4803]=0; + a[4804]=0; + a[4805]=0; + a[4806]=0; + a[4807]=0; + a[4808]=0; + a[4809]=0; + a[4810]=0; + a[4811]=0; + a[4812]=0; + a[4813]=0; + a[4814]=0; + a[4815]=0; + a[4816]=0; + a[4817]=0; + a[4818]=0; + a[4819]=0; + a[4820]=0; + a[4821]=0; + a[4822]=0; + a[4823]=0; + a[4824]=0; + a[4825]=0; + a[4826]=0; + a[4827]=0; + a[4828]=0; + a[4829]=0; + a[4830]=0; + a[4831]=0; + a[4832]=0; + a[4833]=0; + a[4834]=0; + a[4835]=0; + a[4836]=0; + a[4837]=0; + a[4838]=0; + a[4839]=0; + a[4840]=0; + a[4841]=0; + a[4842]=0; + a[4843]=0; + a[4844]=0; + a[4845]=0; + a[4846]=0; + a[4847]=0; + a[4848]=0; + a[4849]=0; + a[4850]=0; + a[4851]=0; + a[4852]=0; + a[4853]=0; + a[4854]=0; + a[4855]=0; + a[4856]=0; + a[4857]=0; + a[4858]=0; + a[4859]=0; + a[4860]=0; + a[4861]=0; + a[4862]=0; + a[4863]=0; + a[4864]=0; + a[4865]=0; + a[4866]=0; + a[4867]=0; + a[4868]=0; + a[4869]=0; + a[4870]=0; + a[4871]=0; + a[4872]=0; + a[4873]=0; + a[4874]=0; + a[4875]=0; + a[4876]=0; + a[4877]=0; + a[4878]=0; + a[4879]=0; + a[4880]=0; + a[4881]=0; + a[4882]=0; + a[4883]=0; + a[4884]=0; + a[4885]=0; + a[4886]=0; + a[4887]=0; + a[4888]=0; + a[4889]=0; + a[4890]=0; + a[4891]=0; + a[4892]=0; + a[4893]=0; + a[4894]=0; + a[4895]=0; + a[4896]=0; + a[4897]=0; + a[4898]=0; + a[4899]=0; + a[4900]=0; + a[4901]=0; + a[4902]=0; + a[4903]=0; + a[4904]=0; + a[4905]=0; + a[4906]=0; + a[4907]=0; + a[4908]=0; + a[4909]=0; + a[4910]=0; + a[4911]=0; + a[4912]=0; + a[4913]=0; + a[4914]=0; + a[4915]=0; + a[4916]=0; + a[4917]=0; + a[4918]=0; + a[4919]=0; + a[4920]=0; + a[4921]=0; + a[4922]=0; + a[4923]=0; + a[4924]=0; + a[4925]=0; + a[4926]=0; + a[4927]=0; + a[4928]=0; + a[4929]=0; + a[4930]=0; + a[4931]=0; + a[4932]=0; + a[4933]=0; + a[4934]=0; + a[4935]=0; + a[4936]=0; + a[4937]=0; + a[4938]=0; + a[4939]=0; + a[4940]=0; + a[4941]=0; + a[4942]=0; + a[4943]=0; + a[4944]=0; + a[4945]=0; + a[4946]=0; + a[4947]=0; + a[4948]=0; + a[4949]=0; + a[4950]=0; + a[4951]=0; + a[4952]=0; + a[4953]=0; + a[4954]=0; + a[4955]=0; + a[4956]=0; + a[4957]=0; + a[4958]=0; + a[4959]=0; + a[4960]=0; + a[4961]=0; + a[4962]=0; + a[4963]=0; + a[4964]=0; + a[4965]=0; + a[4966]=0; + a[4967]=0; + a[4968]=0; + a[4969]=0; + a[4970]=0; + a[4971]=0; + a[4972]=0; + a[4973]=0; + a[4974]=0; + a[4975]=0; + a[4976]=0; + a[4977]=0; + a[4978]=0; + a[4979]=0; + a[4980]=0; + a[4981]=0; + a[4982]=0; + a[4983]=0; + a[4984]=0; + a[4985]=0; + a[4986]=0; + a[4987]=0; + a[4988]=0; + a[4989]=0; + a[4990]=0; + a[4991]=0; + a[4992]=0; + a[4993]=0; + a[4994]=0; + a[4995]=0; + a[4996]=0; + a[4997]=0; + a[4998]=0; + a[4999]=0; + return a; +} diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status index db99c80757..4d82418793 100644 --- a/deps/v8/test/test262/test262.status +++ b/deps/v8/test/test262/test262.status @@ -42,20 +42,6 @@ S10.4.2.1_A1: FAIL 15.2.3.6-4-415: FAIL 15.2.3.6-4-420: FAIL -# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1772 -15.2.3.6-4-292-1: FAIL -15.2.3.6-4-293-2: FAIL -15.2.3.6-4-293-3: FAIL -15.2.3.6-4-294-1: FAIL -15.2.3.6-4-295-1: FAIL -15.2.3.6-4-296-1: FAIL -15.2.3.6-4-333-11: FAIL -15.2.3.7-6-a-281: FAIL -15.2.3.7-6-a-282: FAIL -15.2.3.7-6-a-283: FAIL -15.2.3.7-6-a-284: FAIL -15.2.3.7-6-a-285: FAIL - ##################### DELIBERATE INCOMPATIBILITIES ##################### # We deliberately treat arguments to parseInt() with a leading zero as @@ -69,11 +55,6 @@ S15.8.2.16_A7: PASS || FAIL_OK S15.8.2.18_A7: PASS || FAIL_OK S15.8.2.13_A23: PASS || FAIL_OK -# We are silent in some regexp cases where the spec wants us to give -# errors, for compatibility. -S15.10.2.11_A1_T2: FAIL -S15.10.2.11_A1_T3: FAIL - # We are more lenient in which string character escapes we allow than # the spec (7.8.4 p. 19) wants us to be. This is for compatibility. S7.8.4_A6.1_T4: FAIL_OK diff --git a/deps/v8/tools/gyp/v8.gyp b/deps/v8/tools/gyp/v8.gyp index e60a23272a..b244bc18b2 100644 --- a/deps/v8/tools/gyp/v8.gyp +++ b/deps/v8/tools/gyp/v8.gyp @@ -325,7 +325,6 @@ '../../src/handles-inl.h', '../../src/handles.cc', '../../src/handles.h', - '../../src/hashmap.cc', '../../src/hashmap.h', '../../src/heap-inl.h', '../../src/heap.cc', @@ -923,7 +922,6 @@ '../../src/fixed-dtoa.cc', '../../src/fixed-dtoa.h', '../../src/globals.h', - '../../src/hashmap.cc', '../../src/hashmap.h', '../../src/list-inl.h', '../../src/list.h',