Commit 232d9905 authored by ulan@chromium.org's avatar ulan@chromium.org

Reset function info counters after context disposal in incremental marking step.

R=mstarzinger@chromium.org
BUG=117767,V8:1902
TEST=test/cctest/test-heap/ResetSharedFunctionInfoCountersDuringIncrementalMarking

Review URL: https://chromiumcodereview.appspot.com/9903019

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11222 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7b59b1d5
...@@ -205,6 +205,12 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor { ...@@ -205,6 +205,12 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
MarkObject(target); MarkObject(target);
} }
void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {
if (shared->ic_age() != heap_->global_ic_age()) {
shared->ResetForNewContext(heap_->global_ic_age());
}
}
void VisitPointer(Object** p) { void VisitPointer(Object** p) {
Object* obj = *p; Object* obj = *p;
if (obj->NonFailureIsHeapObject()) { if (obj->NonFailureIsHeapObject()) {
......
...@@ -1390,9 +1390,11 @@ void HeapObject::IterateBody(InstanceType type, int object_size, ...@@ -1390,9 +1390,11 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
case EXTERNAL_FLOAT_ARRAY_TYPE: case EXTERNAL_FLOAT_ARRAY_TYPE:
case EXTERNAL_DOUBLE_ARRAY_TYPE: case EXTERNAL_DOUBLE_ARRAY_TYPE:
break; break;
case SHARED_FUNCTION_INFO_TYPE: case SHARED_FUNCTION_INFO_TYPE: {
SharedFunctionInfo::BodyDescriptor::IterateBody(this, v); SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this);
shared->SharedFunctionInfoIterateBody(v);
break; break;
}
#define MAKE_STRUCT_CASE(NAME, Name, name) \ #define MAKE_STRUCT_CASE(NAME, Name, name) \
case NAME##_TYPE: case NAME##_TYPE:
...@@ -7926,6 +7928,12 @@ void SharedFunctionInfo::CompleteInobjectSlackTracking() { ...@@ -7926,6 +7928,12 @@ void SharedFunctionInfo::CompleteInobjectSlackTracking() {
} }
void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
v->VisitSharedFunctionInfo(this);
SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
}
#define DECLARE_TAG(ignore1, name, ignore2) name, #define DECLARE_TAG(ignore1, name, ignore2) name,
const char* const VisitorSynchronization::kTags[ const char* const VisitorSynchronization::kTags[
VisitorSynchronization::kNumberOfSyncTags] = { VisitorSynchronization::kNumberOfSyncTags] = {
...@@ -7983,7 +7991,6 @@ void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { ...@@ -7983,7 +7991,6 @@ void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
} }
void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
VisitPointer(rinfo->target_object_address()); VisitPointer(rinfo->target_object_address());
......
...@@ -5490,6 +5490,8 @@ class SharedFunctionInfo: public HeapObject { ...@@ -5490,6 +5490,8 @@ class SharedFunctionInfo: public HeapObject {
static bool CompileLazy(Handle<SharedFunctionInfo> shared, static bool CompileLazy(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag); ClearExceptionFlag flag);
void SharedFunctionInfoIterateBody(ObjectVisitor* v);
// Casting. // Casting.
static inline SharedFunctionInfo* cast(Object* obj); static inline SharedFunctionInfo* cast(Object* obj);
...@@ -8538,6 +8540,8 @@ class ObjectVisitor BASE_EMBEDDED { ...@@ -8538,6 +8540,8 @@ class ObjectVisitor BASE_EMBEDDED {
// Visit pointer embedded into a code object. // Visit pointer embedded into a code object.
virtual void VisitEmbeddedPointer(RelocInfo* rinfo); virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {}
// Visits a contiguous arrays of external references (references to the C++ // Visits a contiguous arrays of external references (references to the C++
// heap) in the half-open range [start, end). Any or all of the values // heap) in the half-open range [start, end). Any or all of the values
// may be modified on return. // may be modified on return.
......
...@@ -1593,3 +1593,90 @@ TEST(PrototypeTransitionClearing) { ...@@ -1593,3 +1593,90 @@ TEST(PrototypeTransitionClearing) {
HEAP->CollectAllGarbage(Heap::kNoGCFlags); HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK(map->GetPrototypeTransition(*prototype)->IsMap()); CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
} }
TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
i::FLAG_allow_natives_syntax = true;
#ifdef DEBUG
i::FLAG_verify_heap = true;
#endif
InitializeVM();
if (!i::V8::UseCrankshaft()) return;
v8::HandleScope outer_scope;
{
v8::HandleScope scope;
CompileRun(
"function f () {"
" var s = 0;"
" for (var i = 0; i < 100; i++) s += i;"
" return s;"
"}"
"f(); f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
}
Handle<JSFunction> f =
v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(
v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
CHECK(f->IsOptimized());
IncrementalMarking* marking = HEAP->incremental_marking();
marking->Abort();
marking->Start();
// The following two calls will increment HEAP->global_ic_age().
const int kLongIdlePauseInMs = 1000;
v8::V8::ContextDisposedNotification();
v8::V8::IdleNotification(kLongIdlePauseInMs);
while (!marking->IsStopped() && !marking->IsComplete()) {
marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
}
CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age());
CHECK_EQ(0, f->shared()->opt_count());
CHECK_EQ(0, f->shared()->code()->profiler_ticks());
}
TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
i::FLAG_allow_natives_syntax = true;
#ifdef DEBUG
i::FLAG_verify_heap = true;
#endif
InitializeVM();
if (!i::V8::UseCrankshaft()) return;
v8::HandleScope outer_scope;
{
v8::HandleScope scope;
CompileRun(
"function f () {"
" var s = 0;"
" for (var i = 0; i < 100; i++) s += i;"
" return s;"
"}"
"f(); f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
}
Handle<JSFunction> f =
v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(
v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
CHECK(f->IsOptimized());
HEAP->incremental_marking()->Abort();
// The following two calls will increment HEAP->global_ic_age().
// Since incremental marking is off, IdleNotification will do full GC.
const int kLongIdlePauseInMs = 1000;
v8::V8::ContextDisposedNotification();
v8::V8::IdleNotification(kLongIdlePauseInMs);
CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age());
CHECK_EQ(0, f->shared()->opt_count());
CHECK_EQ(0, f->shared()->code()->profiler_ticks());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment