Browse Source

Upgrade V8 to 3.8.2

v0.7.4-release
Ryan Dahl 13 years ago
parent
commit
4eaf4ce26a
  1. 10
      deps/v8/ChangeLog
  2. 4
      deps/v8/build/common.gypi
  3. 11
      deps/v8/src/arm/lithium-arm.cc
  4. 2
      deps/v8/src/arm/lithium-arm.h
  5. 17
      deps/v8/src/arm/lithium-codegen-arm.cc
  6. 2
      deps/v8/src/assembler.cc
  7. 14
      deps/v8/src/ia32/lithium-codegen-ia32.cc
  8. 4
      deps/v8/src/ia32/lithium-ia32.cc
  9. 8
      deps/v8/src/ia32/lithium-ia32.h
  10. 10
      deps/v8/src/mips/builtins-mips.cc
  11. 16
      deps/v8/src/mips/lithium-codegen-mips.cc
  12. 11
      deps/v8/src/mips/lithium-mips.cc
  13. 2
      deps/v8/src/mips/lithium-mips.h
  14. 26
      deps/v8/src/runtime.cc
  15. 0
      deps/v8/src/scanner.cc
  16. 55
      deps/v8/src/type-info.cc
  17. 2
      deps/v8/src/version.cc
  18. 24
      deps/v8/src/x64/lithium-codegen-x64.cc
  19. 11
      deps/v8/src/x64/lithium-x64.cc
  20. 9
      deps/v8/src/x64/lithium-x64.h
  21. 4
      deps/v8/test/cctest/cctest.status
  22. 82
      deps/v8/test/cctest/test-heap.cc
  23. 69
      deps/v8/test/mjsunit/regress/regress-1530.js
  24. 3
      deps/v8/test/test262/test262.status
  25. 8
      deps/v8/tools/gc-nvp-trace-processor.py

10
deps/v8/ChangeLog

@ -1,3 +1,13 @@
2011-12-21: Version 3.8.2
Add max optimization flag to v8 gyp build to ensure V8 is always built
fully optimized in Chrome.
MIPS: Bring MIPS to parity with other platforms.
Optimizations and stability improvements on all platforms.
2011-12-19: Version 3.8.1
Fixed GCC 4.7 warnings. Patch from Tobias Burnus.

4
deps/v8/build/common.gypi

@ -84,6 +84,10 @@
# For a shared library build, results in "libv8-<(soname_version).so".
'soname_version%': '',
# We want max optimization for the V8 build (if this is not set, chrome
# defaults to low optimization settings)
'optimize': 'max',
},
'target_defaults': {
'conditions': [

11
deps/v8/src/arm/lithium-arm.cc

@ -1779,11 +1779,12 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LOperand* temp = TempRegister();
LOperand* value = UseTempRegister(instr->value());
LInstruction* result = new LStoreGlobalCell(value, temp);
if (instr->RequiresHoleCheck()) result = AssignEnvironment(result);
return result;
LOperand* value = UseRegister(instr->value());
// Use a temp to check the value in the cell in the case where we perform
// a hole check.
return instr->RequiresHoleCheck()
? AssignEnvironment(new LStoreGlobalCell(value, TempRegister()))
: new LStoreGlobalCell(value, NULL);
}

2
deps/v8/src/arm/lithium-arm.h

@ -1242,6 +1242,8 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};

17
deps/v8/src/arm/lithium-codegen-arm.cc

@ -2262,27 +2262,26 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register value = ToRegister(instr->InputAt(0));
Register scratch = scratch0();
Register scratch2 = ToRegister(instr->TempAt(0));
Register value = ToRegister(instr->value());
Register cell = scratch0();
// Load the cell.
__ mov(scratch, Operand(Handle<Object>(instr->hydrogen()->cell())));
__ mov(cell, Operand(instr->hydrogen()->cell()));
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ ldr(scratch2,
FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
__ cmp(scratch2, ip);
// We use a temp to check the payload (CompareRoot might clobber ip).
Register payload = ToRegister(instr->TempAt(0));
__ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment());
}
// Store the value.
__ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
// Cells are always rescanned, so no write barrier here.
}

2
deps/v8/src/assembler.cc

@ -1,4 +1,4 @@
// Copyright (c) 2011 Sun Microsystems Inc.
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without

14
deps/v8/src/ia32/lithium-codegen-ia32.cc

@ -2124,26 +2124,20 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register object = ToRegister(instr->TempAt(0));
Register address = ToRegister(instr->TempAt(1));
Register value = ToRegister(instr->InputAt(0));
ASSERT(!value.is(object));
Handle<JSGlobalPropertyCell> cell_handle(instr->hydrogen()->cell());
int offset = JSGlobalPropertyCell::kValueOffset;
__ mov(object, Immediate(cell_handle));
Register value = ToRegister(instr->value());
Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted. We deoptimize in that case.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ cmp(FieldOperand(object, offset), factory()->the_hole_value());
__ cmp(Operand::Cell(cell_handle), factory()->the_hole_value());
DeoptimizeIf(equal, instr->environment());
}
// Store the value.
__ mov(FieldOperand(object, offset), value);
__ mov(Operand::Cell(cell_handle), value);
// Cells are always rescanned, so no write barrier here.
}

4
deps/v8/src/ia32/lithium-ia32.cc

@ -1856,9 +1856,7 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LStoreGlobalCell* result =
new(zone()) LStoreGlobalCell(UseTempRegister(instr->value()),
TempRegister(),
TempRegister());
new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
}

8
deps/v8/src/ia32/lithium-ia32.h

@ -1269,16 +1269,16 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 2, 0> {
};
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 2> {
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 0> {
public:
explicit LStoreGlobalCell(LOperand* value, LOperand* temp1, LOperand* temp2) {
explicit LStoreGlobalCell(LOperand* value) {
inputs_[0] = value;
temps_[0] = temp1;
temps_[1] = temp2;
}
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};

10
deps/v8/src/mips/builtins-mips.cc

@ -400,13 +400,19 @@ static void ArrayNativeCode(MacroAssembler* masm,
// sp[0]: last argument
Label loop, entry;
__ Branch(&entry);
__ Branch(USE_DELAY_SLOT, &entry);
__ mov(t3, sp);
__ bind(&loop);
__ pop(a2);
__ lw(a2, MemOperand(t3));
__ Addu(t3, t3, kPointerSize);
if (FLAG_smi_only_arrays) {
__ JumpIfNotSmi(a2, call_generic_code);
}
__ Addu(t1, t1, -kPointerSize);
__ sw(a2, MemOperand(t1));
__ bind(&entry);
__ Branch(&loop, lt, t0, Operand(t1));
__ mov(sp, t3);
// Remove caller arguments and receiver from the stack, setup return value and
// return.

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

@ -2141,26 +2141,26 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register value = ToRegister(instr->InputAt(0));
Register scratch = scratch0();
Register scratch2 = ToRegister(instr->TempAt(0));
Register value = ToRegister(instr->value());
Register cell = scratch0();
// Load the cell.
__ li(scratch, Operand(Handle<Object>(instr->hydrogen()->cell())));
__ li(cell, Operand(instr->hydrogen()->cell()));
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ lw(scratch2,
FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
// We use a temp to check the payload.
Register payload = ToRegister(instr->TempAt(0));
__ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment(), scratch2, Operand(at));
DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
}
// Store the value.
__ sw(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ sw(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
// Cells are always rescanned, so no write barrier here.
}

11
deps/v8/src/mips/lithium-mips.cc

@ -1782,11 +1782,12 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LOperand* temp = TempRegister();
LOperand* value = UseTempRegister(instr->value());
LInstruction* result = new LStoreGlobalCell(value, temp);
if (instr->RequiresHoleCheck()) result = AssignEnvironment(result);
return result;
LOperand* value = UseRegister(instr->value());
// Use a temp to check the value in the cell in the case where we perform
// a hole check.
return instr->RequiresHoleCheck()
? AssignEnvironment(new LStoreGlobalCell(value, TempRegister()))
: new LStoreGlobalCell(value, NULL);
}

2
deps/v8/src/mips/lithium-mips.h

@ -1242,6 +1242,8 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};

26
deps/v8/src/runtime.cc

@ -4326,12 +4326,26 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
LookupResult result(isolate);
js_object->LocalLookupRealNamedProperty(*name, &result);
// To be compatible with safari we do not change the value on API objects
// in defineProperty. Firefox disagrees here, and actually changes the value.
if (result.IsProperty() &&
(result.type() == CALLBACKS) &&
result.GetCallbackObject()->IsAccessorInfo()) {
return isolate->heap()->undefined_value();
// Special case for callback properties.
if (result.IsProperty() && result.type() == CALLBACKS) {
Object* callback = result.GetCallbackObject();
// To be compatible with Safari we do not change the value on API objects
// in Object.defineProperty(). Firefox disagrees here, and actually changes
// the value.
if (callback->IsAccessorInfo()) {
return isolate->heap()->undefined_value();
}
// Avoid redefining foreign callback as data property, just use the stored
// setter to update the value instead.
// TODO(mstarzinger): So far this only works if property attributes don't
// change, this should be fixed once we cleanup the underlying code.
if (callback->IsForeign() && result.GetAttributes() == attr) {
return js_object->SetPropertyWithCallback(callback,
*name,
*obj_value,
result.holder(),
kStrictMode);
}
}
// Take special care when attributes are different and there is already

0
deps/v8/src/scanner.cc

55
deps/v8/src/type-info.cc

@ -85,7 +85,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
return code->is_keyed_load_stub() &&
code->ic_state() == MONOMORPHIC &&
Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
code->FindFirstMap() != NULL;
code->FindFirstMap() != NULL &&
!CanRetainOtherContext(code->FindFirstMap(), *global_context_);
}
return false;
}
@ -111,7 +112,9 @@ bool TypeFeedbackOracle::StoreIsMonomorphicNormal(Expression* expr) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_keyed_store_stub() &&
code->ic_state() == MONOMORPHIC &&
Code::ExtractTypeFromFlags(code->flags()) == NORMAL;
Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
code->FindFirstMap() != NULL &&
!CanRetainOtherContext(code->FindFirstMap(), *global_context_);
}
return false;
}
@ -144,7 +147,9 @@ Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
Map* first_map = code->FindFirstMap();
ASSERT(first_map != NULL);
return Handle<Map>(first_map);
return CanRetainOtherContext(first_map, *global_context_)
? Handle<Map>::null()
: Handle<Map>(first_map);
}
return Handle<Map>::cast(map_or_code);
}
@ -155,7 +160,11 @@ Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
Handle<Object> map_or_code = GetInfo(expr->id());
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
return Handle<Map>(code->FindFirstMap());
Map* first_map = code->FindFirstMap();
ASSERT(first_map != NULL);
return CanRetainOtherContext(first_map, *global_context_)
? Handle<Map>::null()
: Handle<Map>(first_map);
}
return Handle<Map>::cast(map_or_code);
}
@ -288,7 +297,11 @@ Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
if (state != CompareIC::KNOWN_OBJECTS) {
return Handle<Map>::null();
}
return Handle<Map>(code->FindFirstMap());
Map* first_map = code->FindFirstMap();
ASSERT(first_map != NULL);
return CanRetainOtherContext(first_map, *global_context_)
? Handle<Map>::null()
: Handle<Map>(first_map);
}
@ -451,20 +464,23 @@ void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
// retaining objects from different tabs in Chrome via optimized code.
bool TypeFeedbackOracle::CanRetainOtherContext(Map* map,
Context* global_context) {
Object* constructor = map->constructor();
ASSERT(constructor != NULL);
while (!constructor->IsJSFunction()) {
// If the constructor is not null or a JSFunction, we have to
// conservatively assume that it may retain a global context.
if (!constructor->IsNull()) return true;
// If both, constructor and prototype are null, we conclude
// that no global context will be retained by this map.
if (map->prototype()->IsNull()) return false;
map = JSObject::cast(map->prototype())->map();
Object* constructor = NULL;
while (!map->prototype()->IsNull()) {
constructor = map->constructor();
if (!constructor->IsNull()) {
// If the constructor is not null or a JSFunction, we have to
// conservatively assume that it may retain a global context.
if (!constructor->IsJSFunction()) return true;
// Check if the constructor directly references a foreign context.
if (CanRetainOtherContext(JSFunction::cast(constructor),
global_context)) {
return true;
}
}
map = HeapObject::cast(map->prototype())->map();
}
constructor = map->constructor();
if (constructor->IsNull()) return false;
JSFunction* function = JSFunction::cast(constructor);
return CanRetainOtherContext(function, global_context);
}
@ -498,7 +514,10 @@ void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
RelocInfo* info = it.rinfo();
Object* object = info->target_object();
if (object->IsMap()) {
AddMapIfMissing(Handle<Map>(Map::cast(object)), types);
Map* map = Map::cast(object);
if (!CanRetainOtherContext(map, *global_context_)) {
AddMapIfMissing(Handle<Map>(map), types);
}
}
}
}

2
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 8
#define BUILD_NUMBER 1
#define BUILD_NUMBER 2
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)

24
deps/v8/src/x64/lithium-codegen-x64.cc

@ -2028,25 +2028,27 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register object = ToRegister(instr->TempAt(0));
Register address = ToRegister(instr->TempAt(1));
Register value = ToRegister(instr->InputAt(0));
ASSERT(!value.is(object));
Handle<JSGlobalPropertyCell> cell_handle(instr->hydrogen()->cell());
__ movq(address, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
Register value = ToRegister(instr->value());
Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted. We deoptimize in that case.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ CompareRoot(Operand(address, 0), Heap::kTheHoleValueRootIndex);
// We have a temp because CompareRoot might clobber kScratchRegister.
Register cell = ToRegister(instr->TempAt(0));
ASSERT(!value.is(cell));
__ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
__ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
DeoptimizeIf(equal, instr->environment());
// Store the value.
__ movq(Operand(cell, 0), value);
} else {
// Store the value.
__ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
__ movq(Operand(kScratchRegister, 0), value);
}
// Store the value.
__ movq(Operand(address, 0), value);
// Cells are always rescanned, so no write barrier here.
}

11
deps/v8/src/x64/lithium-x64.cc

@ -1768,11 +1768,12 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LStoreGlobalCell* result =
new LStoreGlobalCell(UseTempRegister(instr->value()),
TempRegister(),
TempRegister());
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
LOperand* value = UseRegister(instr->value());
// Use a temp to avoid reloading the cell value address in the case where
// we perform a hole check.
return instr->RequiresHoleCheck()
? AssignEnvironment(new LStoreGlobalCell(value, TempRegister()))
: new LStoreGlobalCell(value, NULL);
}

9
deps/v8/src/x64/lithium-x64.h

@ -1231,16 +1231,17 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> {
};
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 2> {
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
public:
explicit LStoreGlobalCell(LOperand* value, LOperand* temp1, LOperand* temp2) {
explicit LStoreGlobalCell(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp1;
temps_[1] = temp2;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};

4
deps/v8/test/cctest/cctest.status

@ -52,10 +52,6 @@ test-profile-generator/RecordStackTraceAtStartProfiling: PASS || FAIL
# We do not yet shrink weak maps after they have been emptied by the GC
test-weakmaps/Shrinking: FAIL
# TODO(1823): Fails without snapshot. Temporarily disabled until fixed.
test-heap/LeakGlobalContextViaMap: SKIP
test-heap/LeakGlobalContextViaFunction: SKIP
##############################################################################
[ $arch == arm ]

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

@ -1333,6 +1333,7 @@ static int NumberOfGlobalObjects() {
// Test that we don't embed maps from foreign contexts into
// optimized code.
TEST(LeakGlobalContextViaMap) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
v8::Persistent<v8::Context> ctx2 = v8::Context::New();
@ -1349,7 +1350,8 @@ TEST(LeakGlobalContextViaMap) {
ctx2->Global()->Set(v8_str("o"), v);
v8::Local<v8::Value> res = CompileRun(
"function f() { return o.x; }"
"for (var i = 0; i < 1000000; ++i) f();"
"for (var i = 0; i < 10; ++i) f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
CHECK_EQ(42, res->Int32Value());
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
@ -1368,6 +1370,7 @@ TEST(LeakGlobalContextViaMap) {
// Test that we don't embed functions from foreign contexts into
// optimized code.
TEST(LeakGlobalContextViaFunction) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
v8::Persistent<v8::Context> ctx2 = v8::Context::New();
@ -1384,7 +1387,8 @@ TEST(LeakGlobalContextViaFunction) {
ctx2->Global()->Set(v8_str("o"), v);
v8::Local<v8::Value> res = CompileRun(
"function f(x) { return x(); }"
"for (var i = 0; i < 1000000; ++i) f(o);"
"for (var i = 0; i < 10; ++i) f(o);"
"%OptimizeFunctionOnNextCall(f);"
"f(o);");
CHECK_EQ(42, res->Int32Value());
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
@ -1398,3 +1402,77 @@ TEST(LeakGlobalContextViaFunction) {
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
TEST(LeakGlobalContextViaMapKeyed) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
v8::Persistent<v8::Context> ctx2 = v8::Context::New();
ctx1->Enter();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(4, NumberOfGlobalObjects());
{
v8::HandleScope inner_scope;
CompileRun("var v = [42, 43]");
v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
ctx2->Enter();
ctx2->Global()->Set(v8_str("o"), v);
v8::Local<v8::Value> res = CompileRun(
"function f() { return o[0]; }"
"for (var i = 0; i < 10; ++i) f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
CHECK_EQ(42, res->Int32Value());
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
ctx2.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
TEST(LeakGlobalContextViaMapProto) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
v8::Persistent<v8::Context> ctx2 = v8::Context::New();
ctx1->Enter();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(4, NumberOfGlobalObjects());
{
v8::HandleScope inner_scope;
CompileRun("var v = { y: 42}");
v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
ctx2->Enter();
ctx2->Global()->Set(v8_str("o"), v);
v8::Local<v8::Value> res = CompileRun(
"function f() {"
" var p = {x: 42};"
" p.__proto__ = o;"
" return p.x;"
"}"
"for (var i = 0; i < 10; ++i) f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
CHECK_EQ(42, res->Int32Value());
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
ctx2.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}

69
deps/v8/test/mjsunit/regress/regress-1530.js

@ -0,0 +1,69 @@
// Copyright 2011 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.
// Test that redefining the 'prototype' property of a function object
// does actually set the internal value and does not screw up any
// shadowing between said property and the internal value.
var f = function() {};
// Verify that normal assignment of 'prototype' property works properly
// and updates the internal value.
var x = { foo: 'bar' };
f.prototype = x;
assertSame(f.prototype, x);
assertSame(f.prototype.foo, 'bar');
assertSame(new f().foo, 'bar');
assertSame(Object.getPrototypeOf(new f()), x);
assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, x);
// Verify that 'prototype' behaves like a data property when it comes to
// redefining with Object.defineProperty() and the internal value gets
// updated.
var y = { foo: 'baz' };
Object.defineProperty(f, 'prototype', { value: y, writable: true });
assertSame(f.prototype, y);
assertSame(f.prototype.foo, 'baz');
assertSame(new f().foo, 'baz');
assertSame(Object.getPrototypeOf(new f()), y);
assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, y);
// Verify that the previous redefinition didn't screw up callbacks and
// the internal value still gets updated.
var z = { foo: 'other' };
f.prototype = z;
assertSame(f.prototype, z);
assertSame(f.prototype.foo, 'other');
assertSame(new f().foo, 'other');
assertSame(Object.getPrototypeOf(new f()), z);
assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, z);
// Verify that non-writability of other properties is respected.
assertThrows("Object.defineProperty(f, 'name', { value: {} })");
assertThrows("Object.defineProperty(f, 'length', { value: {} })");
assertThrows("Object.defineProperty(f, 'caller', { value: {} })");
assertThrows("Object.defineProperty(f, 'arguments', { value: {} })");

3
deps/v8/test/test262/test262.status

@ -39,9 +39,6 @@ S8.7_A5_T2: FAIL
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1624
S10.4.2.1_A1: FAIL
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1530
S15.3.3.1_A4: FAIL
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1475
15.2.3.6-4-405: FAIL
15.2.3.6-4-410: FAIL

8
deps/v8/tools/gc-nvp-trace-processor.py

@ -219,7 +219,7 @@ def other_scope(r):
if r['gc'] == 's':
# there is no 'other' scope for scavenging collections.
return 0
return r['pause'] - r['mark'] - r['sweep'] - r['compact'] - r['external']
return r['pause'] - r['mark'] - r['sweep'] - r['external']
def scavenge_scope(r):
if r['gc'] == 's':
@ -238,7 +238,6 @@ plots = [
Plot(Item('Scavenge', scavenge_scope, lc = 'green'),
Item('Marking', 'mark', lc = 'purple'),
Item('Sweep', 'sweep', lc = 'blue'),
Item('Compaction', 'compact', lc = 'red'),
Item('External', 'external', lc = '#489D43'),
Item('Other', other_scope, lc = 'grey'),
Item('IGC Steps', 'stepstook', lc = '#FF6347'))
@ -250,7 +249,6 @@ plots = [
Plot(Item('Scavenge', scavenge_scope, lc = 'green'),
Item('Marking', 'mark', lc = 'purple'),
Item('Sweep', 'sweep', lc = 'blue'),
Item('Compaction', 'compact', lc = 'red'),
Item('External', 'external', lc = '#489D43'),
Item('Other', other_scope, lc = '#ADD8E6'),
Item('External', 'external', lc = '#D3D3D3'))
@ -309,7 +307,6 @@ def process_trace(filename):
trace = parse_gc_trace(filename)
marksweeps = filter(lambda r: r['gc'] == 'ms', trace)
markcompacts = filter(lambda r: r['gc'] == 'mc', trace)
scavenges = filter(lambda r: r['gc'] == 's', trace)
globalgcs = filter(lambda r: r['gc'] != 's', trace)
@ -368,10 +365,8 @@ def process_trace(filename):
stats(out, 'Total in GC', trace, 'pause')
stats(out, 'Scavenge', scavenges, 'pause')
stats(out, 'MarkSweep', marksweeps, 'pause')
stats(out, 'MarkCompact', markcompacts, 'pause')
stats(out, 'Mark', filter(lambda r: r['mark'] != 0, trace), 'mark')
stats(out, 'Sweep', filter(lambda r: r['sweep'] != 0, trace), 'sweep')
stats(out, 'Compact', filter(lambda r: r['compact'] != 0, trace), 'compact')
stats(out,
'External',
filter(lambda r: r['external'] != 0, trace),
@ -379,7 +374,6 @@ def process_trace(filename):
out.write('</table>')
throughput('TOTAL', trace)
throughput('MS', marksweeps)
throughput('MC', markcompacts)
throughput('OLDSPACE', globalgcs)
out.write('<br/>')
for chart in charts:

Loading…
Cancel
Save