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:
parent
afc0724fe6
commit
74d147a25d
@ -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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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() {
|
|||||||
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 {
|
|||||||
// 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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
|||||||
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 @@
|
|||||||
// (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();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user