diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index 44bebae935..e68ee15fde 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -160,7 +160,7 @@ [ 'v8_use_arm_eabi_hardfloat=="true"', { 'defines': [ 'USE_EABI_HARDFLOAT=1', - 'CAN_USE_VFP2_INSTRUCTIONS', + 'CAN_USE_VFP3_INSTRUCTIONS', ], 'target_conditions': [ ['_toolset=="target"', { @@ -399,6 +399,15 @@ }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" \ or OS=="android"', { + 'cflags!': [ + '-O2', + '-Os', + ], + 'cflags': [ + '-fdata-sections', + '-ffunction-sections', + '-O3', + ], 'conditions': [ [ 'gcc_version==44 and clang==0', { 'cflags': [ diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index 0e6ea00058..c1245b2fb6 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -801,6 +801,13 @@ void HClassOfTestAndBranch::PrintDataTo(StringStream* stream) { } +void HWrapReceiver::PrintDataTo(StringStream* stream) { + receiver()->PrintNameTo(stream); + stream->Add(" "); + function()->PrintNameTo(stream); +} + + void HAccessArgumentsAt::PrintDataTo(StringStream* stream) { arguments()->PrintNameTo(stream); stream->Add("["); diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h index 161e6542d9..7225791cd7 100644 --- a/deps/v8/src/hydrogen-instructions.h +++ b/deps/v8/src/hydrogen-instructions.h @@ -2823,6 +2823,8 @@ class HWrapReceiver: public HTemplateInstruction<2> { virtual HValue* Canonicalize(); + virtual void PrintDataTo(StringStream* stream); + DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) }; diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc index 97306a1659..bdca43ed52 100644 --- a/deps/v8/src/hydrogen.cc +++ b/deps/v8/src/hydrogen.cc @@ -7493,7 +7493,10 @@ bool HGraphBuilder::TryCallApply(Call* expr) { return true; } else { // We are inside inlined function and we know exactly what is inside - // arguments object. + // arguments object. But we need to be able to materialize at deopt. + // TODO(mstarzinger): For now we just ensure arguments are pushed + // right after HEnterInlined, but we could be smarter about this. + EnsureArgumentsArePushedForAccess(); HValue* context = environment()->LookupContext(); HValue* wrapped_receiver = diff --git a/deps/v8/src/log-utils.cc b/deps/v8/src/log-utils.cc index a66db3d931..d8d92cbe21 100644 --- a/deps/v8/src/log-utils.cc +++ b/deps/v8/src/log-utils.cc @@ -107,9 +107,6 @@ void Log::Initialize() { // one character so we can escape the loop properly. p--; break; - case 'p': - stream.Add("%d", OS::GetCurrentProcessId()); - break; case 't': { // %t expands to the current time in milliseconds. double time = OS::TimeCurrentMillis(); diff --git a/deps/v8/src/mips/codegen-mips.cc b/deps/v8/src/mips/codegen-mips.cc index 0119c11f53..1da8089635 100644 --- a/deps/v8/src/mips/codegen-mips.cc +++ b/deps/v8/src/mips/codegen-mips.cc @@ -246,7 +246,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( HeapObject::kMapOffset, a3, t5, - kRAHasBeenSaved, + kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); @@ -517,6 +517,50 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, } +void SeqStringSetCharGenerator::Generate(MacroAssembler* masm, + String::Encoding encoding, + Register string, + Register index, + Register value) { + if (FLAG_debug_code) { + __ And(at, index, Operand(kSmiTagMask)); + __ Check(eq, "Non-smi index", at, Operand(zero_reg)); + __ And(at, value, Operand(kSmiTagMask)); + __ Check(eq, "Non-smi value", at, Operand(zero_reg)); + + __ lw(at, FieldMemOperand(string, String::kLengthOffset)); + __ Check(lt, "Index is too large", at, Operand(index)); + + __ Check(ge, "Index is negative", index, Operand(Smi::FromInt(0))); + + __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); + __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); + + __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask)); + static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; + static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; + __ Check(eq, "Unexpected string type", at, + Operand(encoding == String::ONE_BYTE_ENCODING + ? one_byte_seq_type : two_byte_seq_type)); + } + + __ Addu(at, + string, + Operand(SeqString::kHeaderSize - kHeapObjectTag)); + __ SmiUntag(value); + STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); + if (encoding == String::ONE_BYTE_ENCODING) { + __ SmiUntag(index); + __ Addu(at, at, index); + __ sb(value, MemOperand(at)); + } else { + // No need to untag a smi for two-byte addressing. + __ Addu(at, at, index); + __ sh(value, MemOperand(at)); + } +} + + static MemOperand ExpConstant(int index, Register base) { return MemOperand(base, index * kDoubleSize); } diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc index f9f8c404c2..0835bf20a0 100644 --- a/deps/v8/src/mips/full-codegen-mips.cc +++ b/deps/v8/src/mips/full-codegen-mips.cc @@ -3146,6 +3146,38 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) { } +void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { + ZoneList* args = expr->arguments(); + ASSERT_EQ(3, args->length()); + + VisitForStackValue(args->at(1)); // index + VisitForStackValue(args->at(2)); // value + __ pop(a2); + __ pop(a1); + VisitForAccumulatorValue(args->at(0)); // string + + static const String::Encoding encoding = String::ONE_BYTE_ENCODING; + SeqStringSetCharGenerator::Generate(masm_, encoding, v0, a1, a2); + context()->Plug(v0); +} + + +void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { + ZoneList* args = expr->arguments(); + ASSERT_EQ(3, args->length()); + + VisitForStackValue(args->at(1)); // index + VisitForStackValue(args->at(2)); // value + __ pop(a2); + __ pop(a1); + VisitForAccumulatorValue(args->at(0)); // string + + static const String::Encoding encoding = String::TWO_BYTE_ENCODING; + SeqStringSetCharGenerator::Generate(masm_, encoding, v0, a1, a2); + context()->Plug(v0); +} + + void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { // Load the arguments on the stack and call the runtime function. ZoneList* args = expr->arguments(); diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc index 22352e1184..fd7af9f0f5 100644 --- a/deps/v8/src/mips/lithium-codegen-mips.cc +++ b/deps/v8/src/mips/lithium-codegen-mips.cc @@ -1389,6 +1389,15 @@ void LCodeGen::DoDateField(LDateField* instr) { } +void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { + SeqStringSetCharGenerator::Generate(masm(), + instr->encoding(), + ToRegister(instr->string()), + ToRegister(instr->index()), + ToRegister(instr->value())); +} + + void LCodeGen::DoBitNotI(LBitNotI* instr) { Register input = ToRegister(instr->value()); Register result = ToRegister(instr->result()); diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc index 56dd33d246..521b38d0cd 100644 --- a/deps/v8/src/mips/lithium-mips.cc +++ b/deps/v8/src/mips/lithium-mips.cc @@ -1531,6 +1531,16 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { } +LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { + LOperand* string = UseRegister(instr->string()); + LOperand* index = UseRegister(instr->index()); + LOperand* value = UseRegister(instr->value()); + LSeqStringSetChar* result = + new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); + return DefineAsRegister(result); +} + + LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { LOperand* value = UseRegisterOrConstantAtStart(instr->index()); LOperand* length = UseRegister(instr->length()); diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h index 17ef24cb1a..b2ed72a563 100644 --- a/deps/v8/src/mips/lithium-mips.h +++ b/deps/v8/src/mips/lithium-mips.h @@ -148,6 +148,7 @@ class LCodeGen; V(Random) \ V(RegExpLiteral) \ V(Return) \ + V(SeqStringSetChar) \ V(ShiftI) \ V(SmiTag) \ V(SmiUntag) \ @@ -1143,6 +1144,30 @@ class LDateField: public LTemplateInstruction<1, 1, 1> { }; +class LSeqStringSetChar: public LTemplateInstruction<1, 3, 0> { + public: + LSeqStringSetChar(String::Encoding encoding, + LOperand* string, + LOperand* index, + LOperand* value) : encoding_(encoding) { + inputs_[0] = string; + inputs_[1] = index; + inputs_[2] = value; + } + + String::Encoding encoding() { return encoding_; } + LOperand* string() { return inputs_[0]; } + LOperand* index() { return inputs_[1]; } + LOperand* value() { return inputs_[2]; } + + DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") + DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) + + private: + String::Encoding encoding_; +}; + + class LThrow: public LTemplateInstruction<0, 1, 0> { public: explicit LThrow(LOperand* value) { diff --git a/deps/v8/src/v8utils.h b/deps/v8/src/v8utils.h index 111abdf8b8..9072b4e285 100644 --- a/deps/v8/src/v8utils.h +++ b/deps/v8/src/v8utils.h @@ -209,8 +209,6 @@ INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars)); template void CopyChars(sinkchar* dest, const sourcechar* src, int chars) { - ASSERT(chars >= 0); - if (chars == 0) return; sinkchar* limit = dest + chars; #ifdef V8_HOST_CAN_READ_UNALIGNED if (sizeof(*dest) == sizeof(*src)) { diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc index 34ba3fe63a..7d317418d8 100644 --- a/deps/v8/src/version.cc +++ b/deps/v8/src/version.cc @@ -35,7 +35,7 @@ #define MAJOR_VERSION 3 #define MINOR_VERSION 15 #define BUILD_NUMBER 11 -#define PATCH_LEVEL 7 +#define PATCH_LEVEL 10 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) #define IS_CANDIDATE_VERSION 0 diff --git a/deps/v8/test/mjsunit/regress/regress-2489.js b/deps/v8/test/mjsunit/regress/regress-2489.js new file mode 100644 index 0000000000..882c4f794a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-2489.js @@ -0,0 +1,50 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * 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 + +"use strict"; + +function f(a, b) { + return g("c", "d"); +} + +function g(a, b) { + g.constructor.apply(this, arguments); +} + +g.constructor = function(a, b) { + assertEquals("c", a); + assertEquals("d", b); +} + +f("a", "b"); +f("a", "b"); +%OptimizeFunctionOnNextCall(f); +f("a", "b"); +g.x = "deopt"; +f("a", "b"); diff --git a/deps/v8/tools/run-tests.py b/deps/v8/tools/run-tests.py index c09ea064d9..f20af169d2 100755 --- a/deps/v8/tools/run-tests.py +++ b/deps/v8/tools/run-tests.py @@ -155,7 +155,7 @@ def ProcessOptions(options): options.mode = tokens[1] options.mode = options.mode.split(",") for mode in options.mode: - if not mode in ["debug", "release"]: + if not mode.lower() in ["debug", "release"]: print "Unknown mode %s" % mode return False if options.arch in ["auto", "native"]: