Commit 74d147a2 authored by ulan@chromium.org's avatar ulan@chromium.org

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
parent afc0724f
...@@ -469,7 +469,7 @@ DEFINE_bool(trace_external_memory, false, ...@@ -469,7 +469,7 @@ DEFINE_bool(trace_external_memory, false,
"it is adjusted.") "it is adjusted.")
DEFINE_bool(collect_maps, true, DEFINE_bool(collect_maps, true,
"garbage collect maps from which no objects can be reached") "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") "make maps embedded in optimized code weak")
DEFINE_bool(flush_code, true, DEFINE_bool(flush_code, true,
"flush code that we expect not to use again (during full gc)") "flush code that we expect not to use again (during full gc)")
......
...@@ -2181,6 +2181,32 @@ void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) { ...@@ -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() { void MarkCompactCollector::MarkLiveObjects() {
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
// The recursive GC marker detects when it is nearing stack overflow, // The recursive GC marker detects when it is nearing stack overflow,
...@@ -2260,6 +2286,8 @@ void MarkCompactCollector::MarkLiveObjects() { ...@@ -2260,6 +2286,8 @@ void MarkCompactCollector::MarkLiveObjects() {
RootMarkingVisitor root_visitor(heap()); RootMarkingVisitor root_visitor(heap());
MarkRoots(&root_visitor); MarkRoots(&root_visitor);
ProcessTopOptimizedFrame(&root_visitor);
// The objects reachable from the roots are marked, yet unreachable // The objects reachable from the roots are marked, yet unreachable
// objects are unmarked. Mark objects reachable due to host // objects are unmarked. Mark objects reachable due to host
// application specific logic or through Harmony weak maps. // application specific logic or through Harmony weak maps.
......
...@@ -853,6 +853,11 @@ class MarkCompactCollector { ...@@ -853,6 +853,11 @@ class MarkCompactCollector {
// or implicit references' groups. // or implicit references' groups.
void ProcessEphemeralMarking(ObjectVisitor* visitor); 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 // Mark objects reachable (transitively) from objects in the marking
// stack. This function empties the marking stack, but may leave // stack. This function empties the marking stack, but may leave
// overflowed objects in the heap, in which case the marking stack's // overflowed objects in the heap, in which case the marking stack's
......
...@@ -10385,6 +10385,19 @@ void Code::PrintDeoptLocation(int bailout_id) { ...@@ -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. // Identify kind of code.
const char* Code::Kind2String(Kind kind) { const char* Code::Kind2String(Kind kind) {
switch (kind) { switch (kind) {
......
...@@ -4841,6 +4841,7 @@ class Code: public HeapObject { ...@@ -4841,6 +4841,7 @@ class Code: public HeapObject {
int GetAge(); int GetAge();
void PrintDeoptLocation(int bailout_id); void PrintDeoptLocation(int bailout_id);
bool CanDeoptAt(Address pc);
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
void VerifyEmbeddedMapsDependency(); void VerifyEmbeddedMapsDependency();
......
...@@ -25,16 +25,13 @@ ...@@ -25,16 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax // Flags: --noanalyze_environment_liveness
var r = /r/; var r = /r/;
var a = "";
function f() { function f() {
%OptimizeFunctionOnNextCall(f, "osr"); r[r] = function() {};
for (var i = 0; i < 1000000; i++) {
a += i.toString();
r[r] = function() {};
}
} }
f(); for (var i = 0; i < 300000; i++) {
f();
}
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