Enable weak embedded maps in optimized code.

If the top optimized code in call stack is at the point that does not support
deoptimization, then treat the maps in the code as strong pointers.

Note that other optimized code in call stack must support deoptimization
because of the call instruction with side-effects.

BUG=217858,v8:2073
R=mstarzinger@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15452 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ulan@chromium.org 2013-07-02 15:15:58 +00:00
parent afc0724fe6
commit 74d147a25d
6 changed files with 53 additions and 9 deletions

View File

@ -469,7 +469,7 @@ DEFINE_bool(trace_external_memory, false,
"it is adjusted.")
DEFINE_bool(collect_maps, true,
"garbage collect maps from which no objects can be reached")
DEFINE_bool(weak_embedded_maps_in_optimized_code, false,
DEFINE_bool(weak_embedded_maps_in_optimized_code, true,
"make maps embedded in optimized code weak")
DEFINE_bool(flush_code, true,
"flush code that we expect not to use again (during full gc)")

View File

@ -2181,6 +2181,32 @@ void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) {
}
static StackFrame* TopOptimizedFrame(Isolate* isolate) {
for (StackFrameIterator it(isolate, isolate->thread_local_top());
!it.done(); it.Advance()) {
if (it.frame()->type() == StackFrame::JAVA_SCRIPT) {
return NULL;
}
if (it.frame()->type() == StackFrame::OPTIMIZED) {
return it.frame();
}
}
return NULL;
}
void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
StackFrame* frame = TopOptimizedFrame(isolate());
if (frame != NULL) {
Code* code = frame->LookupCode();
if (!code->CanDeoptAt(frame->pc())) {
code->CodeIterateBody(visitor);
}
ProcessMarkingDeque();
}
}
void MarkCompactCollector::MarkLiveObjects() {
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
// The recursive GC marker detects when it is nearing stack overflow,
@ -2260,6 +2286,8 @@ void MarkCompactCollector::MarkLiveObjects() {
RootMarkingVisitor root_visitor(heap());
MarkRoots(&root_visitor);
ProcessTopOptimizedFrame(&root_visitor);
// The objects reachable from the roots are marked, yet unreachable
// objects are unmarked. Mark objects reachable due to host
// application specific logic or through Harmony weak maps.

View File

@ -853,6 +853,11 @@ class MarkCompactCollector {
// or implicit references' groups.
void ProcessEphemeralMarking(ObjectVisitor* visitor);
// If the call-site of the top optimized code was not prepared for
// deoptimization, then treat the maps in the code as strong pointers,
// otherwise a map can die and deoptimize the code.
void ProcessTopOptimizedFrame(ObjectVisitor* visitor);
// Mark objects reachable (transitively) from objects in the marking
// stack. This function empties the marking stack, but may leave
// overflowed objects in the heap, in which case the marking stack's

View File

@ -10385,6 +10385,19 @@ void Code::PrintDeoptLocation(int bailout_id) {
}
bool Code::CanDeoptAt(Address pc) {
DeoptimizationInputData* deopt_data =
DeoptimizationInputData::cast(deoptimization_data());
Address code_start_address = instruction_start();
for (int i = 0; i < deopt_data->DeoptCount(); i++) {
if (deopt_data->Pc(i)->value() == -1) continue;
Address address = code_start_address + deopt_data->Pc(i)->value();
if (address == pc) return true;
}
return false;
}
// Identify kind of code.
const char* Code::Kind2String(Kind kind) {
switch (kind) {

View File

@ -4841,6 +4841,7 @@ class Code: public HeapObject {
int GetAge();
void PrintDeoptLocation(int bailout_id);
bool CanDeoptAt(Address pc);
#ifdef VERIFY_HEAP
void VerifyEmbeddedMapsDependency();

View File

@ -25,16 +25,13 @@
// (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
// Flags: --noanalyze_environment_liveness
var r = /r/;
var a = "";
function f() {
%OptimizeFunctionOnNextCall(f, "osr");
for (var i = 0; i < 1000000; i++) {
a += i.toString();
r[r] = function() {};
}
r[r] = function() {};
}
f();
for (var i = 0; i < 300000; i++) {
f();
}