Browse Source

V8: Upgrade to 3.15.11.15

v0.9.10-release
isaacs 12 years ago
parent
commit
0c2e5ec840
  1. 11
      deps/v8/build/common.gypi
  2. 2
      deps/v8/src/compiler.cc
  3. 2
      deps/v8/src/hydrogen.cc
  4. 3
      deps/v8/src/log-utils.cc
  5. 36
      deps/v8/src/mark-compact.cc
  6. 1
      deps/v8/src/mark-compact.h
  7. 1
      deps/v8/src/messages.js
  8. 8
      deps/v8/src/mips/codegen-mips.cc
  9. 2
      deps/v8/src/mips/lithium-codegen-mips.cc
  10. 20
      deps/v8/src/objects-inl.h
  11. 2
      deps/v8/src/objects.cc
  12. 2
      deps/v8/src/objects.h
  13. 17
      deps/v8/src/platform-posix.cc
  14. 21
      deps/v8/src/runtime.cc
  15. 15
      deps/v8/src/string.js
  16. 2
      deps/v8/src/v8utils.h
  17. 2
      deps/v8/src/version.cc
  18. 125
      deps/v8/test/cctest/test-heap.cc
  19. 81
      deps/v8/test/mjsunit/regress/regress-2437.js
  20. 40
      deps/v8/test/mjsunit/regress/regress-2499.js
  21. 33
      deps/v8/test/mjsunit/regress/regress-crbug-170856.js

11
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': [

2
deps/v8/src/compiler.cc

@ -697,7 +697,7 @@ static bool InstallFullCode(CompilationInfo* info) {
Handle<ScopeInfo> scope_info =
ScopeInfo::Create(info->scope(), info->zone());
shared->set_scope_info(*scope_info);
shared->set_code(*code);
shared->ReplaceCode(*code);
if (!function.is_null()) {
function->ReplaceCode(*code);
ASSERT(!function->IsOptimized());

2
deps/v8/src/hydrogen.cc

@ -8306,6 +8306,7 @@ static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
HValue* const32_minus_sa) {
if (!const32_minus_sa->IsSub()) return false;
HSub* sub = HSub::cast(const32_minus_sa);
if (sa != sub->right()) return false;
HValue* const32 = sub->left();
if (!const32->IsConstant() ||
HConstant::cast(const32)->Integer32Value() != 32) {
@ -8334,6 +8335,7 @@ bool HGraphBuilder::MatchRotateRight(HValue* left,
} else {
return false;
}
if (shl->left() != shr->left()) return false;
if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) &&
!ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) {

3
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();

36
deps/v8/src/mark-compact.cc

@ -885,8 +885,8 @@ void CodeFlusher::ProcessJSFunctionCandidates() {
if (!code_mark.Get()) {
shared->set_code(lazy_compile);
candidate->set_code(lazy_compile);
} else if (code == lazy_compile) {
candidate->set_code(lazy_compile);
} else {
candidate->set_code(code);
}
// We are in the middle of a GC cycle so the write barrier in the code
@ -935,13 +935,40 @@ void CodeFlusher::ProcessSharedFunctionInfoCandidates() {
}
void CodeFlusher::EvictCandidate(SharedFunctionInfo* shared_info) {
// Make sure previous flushing decisions are revisited.
isolate_->heap()->incremental_marking()->RecordWrites(shared_info);
SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
SharedFunctionInfo* next_candidate;
if (candidate == shared_info) {
next_candidate = GetNextCandidate(shared_info);
shared_function_info_candidates_head_ = next_candidate;
ClearNextCandidate(shared_info);
} else {
while (candidate != NULL) {
next_candidate = GetNextCandidate(candidate);
if (next_candidate == shared_info) {
next_candidate = GetNextCandidate(shared_info);
SetNextCandidate(candidate, next_candidate);
ClearNextCandidate(shared_info);
break;
}
candidate = next_candidate;
}
}
}
void CodeFlusher::EvictCandidate(JSFunction* function) {
ASSERT(!function->next_function_link()->IsUndefined());
Object* undefined = isolate_->heap()->undefined_value();
// The function is no longer a candidate, make sure it gets visited
// again so that previous flushing decisions are revisited.
// Make sure previous flushing decisions are revisited.
isolate_->heap()->incremental_marking()->RecordWrites(function);
isolate_->heap()->incremental_marking()->RecordWrites(function->shared());
JSFunction* candidate = jsfunction_candidates_head_;
JSFunction* next_candidate;
@ -957,6 +984,7 @@ void CodeFlusher::EvictCandidate(JSFunction* function) {
next_candidate = GetNextCandidate(function);
SetNextCandidate(candidate, next_candidate);
ClearNextCandidate(function, undefined);
break;
}
candidate = next_candidate;

1
deps/v8/src/mark-compact.h

@ -434,6 +434,7 @@ class CodeFlusher {
}
}
void EvictCandidate(SharedFunctionInfo* shared_info);
void EvictCandidate(JSFunction* function);
void ProcessCandidates() {

1
deps/v8/src/messages.js

@ -1090,6 +1090,7 @@ function captureStackTrace(obj, cons_opt) {
// with a data property as soon as the stack trace has been formatted.
var getter = function() {
var value = FormatRawStackTrace(obj, raw_stack);
raw_stack = void 0;
%DefineOrRedefineDataProperty(obj, 'stack', value, NONE);
return value;
};

8
deps/v8/src/mips/codegen-mips.cc

@ -529,9 +529,9 @@ void SeqStringSetCharGenerator::Generate(MacroAssembler* masm,
__ 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(lt, "Index is too large", index, Operand(at));
__ Check(ge, "Index is negative", index, Operand(Smi::FromInt(0)));
__ Check(ge, "Index is negative", index, Operand(zero_reg));
__ lw(at, FieldMemOperand(string, HeapObject::kMapOffset));
__ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset));
@ -539,9 +539,9 @@ void SeqStringSetCharGenerator::Generate(MacroAssembler* masm,
__ 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
__ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING
? one_byte_seq_type : two_byte_seq_type));
__ Check(eq, "Unexpected string type", at, Operand(zero_reg));
}
__ Addu(at,

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

@ -4016,7 +4016,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ Branch(&not_applicable, ne, scratch, Operand(from_map));
__ li(new_map_reg, Operand(to_map));
if (IsFastSmiElementsKind(from_kind) && IsFastObjectElementsKind(to_kind)) {
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
__ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
// Write barrier.
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,

20
deps/v8/src/objects-inl.h

@ -4368,6 +4368,19 @@ void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
}
void SharedFunctionInfo::ReplaceCode(Code* value) {
// If the GC metadata field is already used then the function was
// enqueued as a code flushing candidate and we remove it now.
if (code()->gc_metadata() != NULL) {
CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
flusher->EvictCandidate(this);
}
ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
set_code(value);
}
ScopeInfo* SharedFunctionInfo::scope_info() {
return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
}
@ -4955,13 +4968,6 @@ void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
}
void JSRegExp::ResetLastIndex() {
InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
Smi::FromInt(0),
SKIP_WRITE_BARRIER); // It's a Smi.
}
ElementsKind JSObject::GetElementsKind() {
ElementsKind kind = map()->elements_kind();
#if DEBUG

2
deps/v8/src/objects.cc

@ -8562,7 +8562,7 @@ void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) {
// old code, we have to replace it. We should try to avoid this
// altogether because it flushes valuable type feedback by
// effectively resetting all IC state.
set_code(recompiled);
ReplaceCode(recompiled);
}
ASSERT(has_deoptimization_support());
}

2
deps/v8/src/objects.h

@ -5429,6 +5429,7 @@ class SharedFunctionInfo: public HeapObject {
// [code]: Function code.
DECL_ACCESSORS(code, Code)
inline void ReplaceCode(Code* code);
// [optimized_code_map]: Map from native context to optimized code
// and a shared literals array or Smi 0 if none.
@ -6648,7 +6649,6 @@ class JSRegExp: public JSObject {
inline Object* DataAtUnchecked(int index);
inline void SetDataAtUnchecked(int index, Object* value, Heap* heap);
inline Type TypeTagUnchecked();
inline void ResetLastIndex();
static int code_index(bool is_ascii) {
if (is_ascii) {

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

@ -109,20 +109,11 @@ void* OS::GetRandomMmapAddr() {
raw_addr &= V8_UINT64_C(0x3ffffffff000);
#else
uint32_t raw_addr = V8::RandomPrivate(isolate);
// For our 32-bit mmap() hint, we pick a random address in the bottom
// half of the top half of the address space (that is, the third quarter).
// Because we do not MAP_FIXED, this will be treated only as a hint -- the
// system will not fail to mmap() because something else happens to already
// be mapped at our random address. We deliberately set the hint high enough
// to get well above the system's break (that is, the heap); systems will
// either try the hint and if that fails move higher (MacOS and other BSD
// derivatives) or try the hint and if that fails allocate as if there were
// no hint at all (Linux, Solaris, illumos and derivatives). The high hint
// prevents the break from getting hemmed in at low values, ceding half of
// the address space to the system heap.
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
// 10.6 and 10.7.
raw_addr &= 0x3ffff000;
raw_addr += 0x80000000;
raw_addr += 0x20000000;
#endif
return reinterpret_cast<void*>(raw_addr);
}

21
deps/v8/src/runtime.cc

@ -1098,14 +1098,15 @@ static MaybeObject* GetOwnProperty(Isolate* isolate,
PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name);
if (attrs == ABSENT) return heap->undefined_value();
AccessorPair* accessors = obj->GetLocalPropertyAccessorPair(*name);
AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name);
Handle<AccessorPair> accessors(raw_accessors, isolate);
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(accessors != NULL));
elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL));
if (accessors == NULL) {
if (raw_accessors == NULL) {
elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
// GetProperty does access check.
Handle<Object> value = GetProperty(obj, name);
@ -1790,7 +1791,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(
JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
regexp->ResetLastIndex();
regexp->InObjectPropertyAtPut(
JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
return regexp;
}
@ -2145,7 +2147,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
// target function to undefined. SetCode is only used for built-in
// constructors like String, Array, and Object, and some web code
// doesn't like seeing source code for constructors.
target_shared->set_code(source_shared->code());
target_shared->ReplaceCode(source_shared->code());
target_shared->set_scope_info(source_shared->scope_info());
target_shared->set_length(source_shared->length());
target_shared->set_formal_parameter_count(
@ -2903,8 +2905,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString(
int matches = indices.length();
if (matches == 0) {
pattern_regexp->ResetLastIndex();
return *subject;
return isolate->heap()->undefined_value();
}
// Detect integer overflow.
@ -3005,8 +3006,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
int32_t* current_match = global_cache.FetchNext();
if (current_match == NULL) {
if (global_cache.HasException()) return Failure::Exception();
regexp->ResetLastIndex();
return *subject;
return isolate->heap()->undefined_value();
}
// Guessing the number of parts that the final result string is built
@ -3104,8 +3104,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
int32_t* current_match = global_cache.FetchNext();
if (current_match == NULL) {
if (global_cache.HasException()) return Failure::Exception();
regexp->ResetLastIndex();
return *subject;
return isolate->heap()->undefined_value();
}
int start = current_match[0];

15
deps/v8/src/string.js

@ -194,6 +194,7 @@ function StringMatch(regexp) {
// lastMatchInfo is defined in regexp.js.
var result = %StringMatch(subject, regexp, lastMatchInfo);
if (result !== null) lastMatchInfoOverride = null;
regexp.lastIndex = 0;
return result;
}
// Non-regexp argument.
@ -244,10 +245,16 @@ function StringReplace(search, replace) {
}
} else {
if (lastMatchInfoOverride == null) {
return %StringReplaceRegExpWithString(subject,
var answer = %StringReplaceRegExpWithString(subject,
search,
TO_STRING_INLINE(replace),
lastMatchInfo);
if (IS_UNDEFINED(answer)) { // No match. Return subject string.
search.lastIndex = 0;
return subject;
}
if (search.global) search.lastIndex = 0;
return answer;
} else {
// We use this hack to detect whether StringReplaceRegExpWithString
// found at least one hit. In that case we need to remove any
@ -258,11 +265,17 @@ function StringReplace(search, replace) {
search,
TO_STRING_INLINE(replace),
lastMatchInfo);
if (IS_UNDEFINED(answer)) { // No match. Return subject string.
search.lastIndex = 0;
lastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject;
return subject;
}
if (%_IsSmi(lastMatchInfo[LAST_SUBJECT_INDEX])) {
lastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject;
} else {
lastMatchInfoOverride = null;
}
if (search.global) search.lastIndex = 0;
return answer;
}
}

2
deps/v8/src/v8utils.h

@ -209,8 +209,6 @@ INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
template <typename sourcechar, typename sinkchar>
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)) {

2
deps/v8/src/version.cc

@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 15
#define BUILD_NUMBER 11
#define PATCH_LEVEL 10
#define PATCH_LEVEL 15
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0

125
deps/v8/test/cctest/test-heap.cc

@ -2575,3 +2575,128 @@ TEST(Regress159140) {
// Unoptimized code is missing and the deoptimizer will go ballistic.
CompileRun("g('bozo');");
}
TEST(Regress169209) {
i::FLAG_allow_natives_syntax = true;
i::FLAG_flush_code_incrementally = true;
InitializeVM();
v8::HandleScope scope;
// Perform one initial GC to enable code flushing.
HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
// Prepare a shared function info eligible for code flushing for which
// the unoptimized code will be replaced during optimization.
Handle<SharedFunctionInfo> shared1;
{
HandleScope inner_scope;
CompileRun("function f() { return 'foobar'; }"
"function g(x) { if (x) f(); }"
"f();"
"g(false);"
"g(false);");
Handle<JSFunction> f =
v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(
v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
CHECK(f->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
}
shared1 = inner_scope.CloseAndEscape(handle(f->shared(), ISOLATE));
}
// Prepare a shared function info eligible for code flushing that will
// represent the dangling tail of the candidate list.
Handle<SharedFunctionInfo> shared2;
{
HandleScope inner_scope;
CompileRun("function flushMe() { return 0; }"
"flushMe(1);");
Handle<JSFunction> f =
v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(
v8::Context::GetCurrent()->Global()->Get(v8_str("flushMe"))));
CHECK(f->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
}
shared2 = inner_scope.CloseAndEscape(handle(f->shared(), ISOLATE));
}
// Simulate incremental marking and collect code flushing candidates.
SimulateIncrementalMarking();
CHECK(shared1->code()->gc_metadata() != NULL);
// Optimize function and make sure the unoptimized code is replaced.
#ifdef DEBUG
FLAG_stop_at = "f";
#endif
CompileRun("%OptimizeFunctionOnNextCall(g);"
"g(false);");
// Finish garbage collection cycle.
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK(shared1->code()->gc_metadata() == NULL);
}
TEST(Regress168801) {
i::FLAG_always_compact = true;
i::FLAG_cache_optimized_code = false;
i::FLAG_allow_natives_syntax = true;
i::FLAG_flush_code_incrementally = true;
InitializeVM();
v8::HandleScope scope;
// Perform one initial GC to enable code flushing.
HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
// Ensure the code ends up on an evacuation candidate.
SimulateFullSpace(HEAP->code_space());
// Prepare an unoptimized function that is eligible for code flushing.
Handle<JSFunction> function;
{
HandleScope inner_scope;
CompileRun("function mkClosure() {"
" return function(x) { return x + 1; };"
"}"
"var f = mkClosure();"
"f(1); f(2);");
Handle<JSFunction> f =
v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(
v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
CHECK(f->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
}
function = inner_scope.CloseAndEscape(handle(*f, ISOLATE));
}
// Simulate incremental marking so that unoptimized function is enqueued as a
// candidate for code flushing. The shared function info however will not be
// explicitly enqueued.
SimulateIncrementalMarking();
// Now optimize the function so that it is taken off the candidate list.
{
HandleScope inner_scope;
CompileRun("%OptimizeFunctionOnNextCall(f); f(3);");
}
// This cycle will bust the heap and subsequent cycles will go ballistic.
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
}

81
deps/v8/test/mjsunit/regress/regress-2437.js

@ -25,6 +25,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Summary of the spec: lastIndex is reset to 0 if
// - a regexp fails to match, regardless of global or non-global.
// - a global regexp is used in a function that returns multiple results,
// such as String.prototype.replace or String.prototype.match, since it
// repeats the regexp until it fails to match.
// Otherwise lastIndex is only set when a global regexp matches, to the index
// after the match.
// Test Regexp.prototype.exec
r = /a/;
r.lastIndex = 1;
@ -73,3 +81,76 @@ r.lastIndex = 1;
"zzzz".replace(r, function() { return ""; });
assertEquals(0, r.lastIndex);
// Regexp functions that returns multiple results:
// A global regexp always resets lastIndex regardless of whether it matches.
r = /a/g;
r.lastIndex = -1;
"0123abcd".replace(r, "x");
assertEquals(0, r.lastIndex);
r.lastIndex = -1;
"01234567".replace(r, "x");
assertEquals(0, r.lastIndex);
r.lastIndex = -1;
"0123abcd".match(r);
assertEquals(0, r.lastIndex);
r.lastIndex = -1;
"01234567".match(r);
assertEquals(0, r.lastIndex);
// A non-global regexp resets lastIndex iff it does not match.
r = /a/;
r.lastIndex = -1;
"0123abcd".replace(r, "x");
assertEquals(-1, r.lastIndex);
r.lastIndex = -1;
"01234567".replace(r, "x");
assertEquals(0, r.lastIndex);
r.lastIndex = -1;
"0123abcd".match(r);
assertEquals(-1, r.lastIndex);
r.lastIndex = -1;
"01234567".match(r);
assertEquals(0, r.lastIndex);
// Also test RegExp.prototype.exec and RegExp.prototype.test
r = /a/g;
r.lastIndex = 1;
r.exec("01234567");
assertEquals(0, r.lastIndex);
r.lastIndex = 1;
r.exec("0123abcd");
assertEquals(5, r.lastIndex);
r = /a/;
r.lastIndex = 1;
r.exec("01234567");
assertEquals(0, r.lastIndex);
r.lastIndex = 1;
r.exec("0123abcd");
assertEquals(1, r.lastIndex);
r = /a/g;
r.lastIndex = 1;
r.test("01234567");
assertEquals(0, r.lastIndex);
r.lastIndex = 1;
r.test("0123abcd");
assertEquals(5, r.lastIndex);
r = /a/;
r.lastIndex = 1;
r.test("01234567");
assertEquals(0, r.lastIndex);
r.lastIndex = 1;
r.test("0123abcd");
assertEquals(1, r.lastIndex);

40
deps/v8/test/mjsunit/regress/regress-2499.js

@ -0,0 +1,40 @@
// 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
function foo(word, nBits) {
return (word[1] >>> nBits) | (word[0] << (32 - nBits));
}
word = [0x1001, 0];
var expected = foo(word, 1);
foo(word, 1);
%OptimizeFunctionOnNextCall(foo);
var optimized = foo(word, 1);
assertEquals(expected, optimized)

33
deps/v8/test/mjsunit/regress/regress-crbug-170856.js

@ -0,0 +1,33 @@
// 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.
r = new RegExp("a");
for (var i = 0; i < 100; i++) {
r["abc" + i] = i;
}
"zzzz".replace(r, "");
assertEquals(0, r.lastIndex);
Loading…
Cancel
Save