diff --git a/src/api.cc b/src/api.cc index bac3069308..4146bd4c1d 100644 --- a/src/api.cc +++ b/src/api.cc @@ -741,6 +741,7 @@ void Context::Exit() { i::Context* last_context = isolate->handle_scope_implementer()->RestoreContext(); isolate->set_context(last_context); + isolate->set_context_exit_happened(true); } diff --git a/src/heap.cc b/src/heap.cc index b59eb50ddf..fff1319b28 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -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: @@ -872,6 +872,8 @@ void Heap::MarkCompact(GCTracer* tracer) { isolate_->counters()->objs_since_last_full()->Set(0); contexts_disposed_ = 0; + + isolate_->set_context_exit_happened(false); } diff --git a/src/heap.h b/src/heap.h index 0ac76c9d57..937b034e22 100644 --- a/src/heap.h +++ b/src/heap.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: diff --git a/src/isolate.cc b/src/isolate.cc index f66a22db13..82af337d90 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -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: @@ -1454,7 +1454,8 @@ Isolate::Isolate() has_installed_extensions_(false), string_tracker_(NULL), regexp_stack_(NULL), - embedder_data_(NULL) { + embedder_data_(NULL), + context_exit_happened_(false) { TRACE_ISOLATE(constructor); memset(isolate_addresses_, 0, diff --git a/src/isolate.h b/src/isolate.h index 898c1783dd..89793f8c74 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -1023,6 +1023,13 @@ class Isolate { thread_local_top_.top_lookup_result_ = top; } + bool context_exit_happened() { + return context_exit_happened_; + } + void set_context_exit_happened(bool context_exit_happened) { + context_exit_happened_ = context_exit_happened; + } + private: Isolate(); @@ -1188,6 +1195,10 @@ class Isolate { unibrow::Mapping interp_canonicalize_mapping_; void* embedder_data_; + // The garbage collector should be a little more aggressive when it knows + // that a context was recently exited. + bool context_exit_happened_; + #if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \ defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__) bool simulator_initialized_; diff --git a/src/mark-compact.cc b/src/mark-compact.cc index 7f08de9b83..bfec2c660b 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -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: @@ -63,6 +63,7 @@ MarkCompactCollector::MarkCompactCollector() : // NOLINT compacting_(false), was_marked_incrementally_(false), collect_maps_(FLAG_collect_maps), + flush_monomorphic_ics_(false), tracer_(NULL), migration_slots_buffer_(NULL), heap_(NULL), @@ -515,6 +516,12 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) { // order which is not implemented for incremental marking. collect_maps_ = FLAG_collect_maps && !was_marked_incrementally_; + // Monomorphic ICs are preserved when possible, but need to be flushed + // when they might be keeping a Context alive, or when the heap is about + // to be serialized. + flush_monomorphic_ics_ = + heap()->isolate()->context_exit_happened() || Serializer::enabled(); + // Rather than passing the tracer around we stash it in a static member // variable. tracer_ = tracer; @@ -881,7 +888,9 @@ class StaticMarkingVisitor : public StaticVisitorBase { static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); - if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()) { + if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() + && (target->ic_state() == MEGAMORPHIC || + heap->mark_compact_collector()->flush_monomorphic_ics_)) { IC::Clear(rinfo->pc()); target = Code::GetCodeFromTargetAddress(rinfo->target_address()); } else { diff --git a/src/mark-compact.h b/src/mark-compact.h index 51e172b98a..d3d495f5b8 100644 --- a/src/mark-compact.h +++ b/src/mark-compact.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: @@ -580,6 +580,8 @@ class MarkCompactCollector { bool collect_maps_; + bool flush_monomorphic_ics_; + // A pointer to the current stack-allocated GC tracer object during a full // collection (NULL before and after). GCTracer* tracer_;