Commit 0a4047a6 authored by jarin's avatar jarin Committed by Commit bot

During arguments materialization, do not store materialized objects without lazy deopt.

BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/919173003

Cr-Commit-Position: refs/heads/master@{#26695}
parent 7c15df81
...@@ -3190,7 +3190,10 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument( ...@@ -3190,7 +3190,10 @@ SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
int inlined_jsframe_index, int inlined_jsframe_index,
int formal_parameter_count) int formal_parameter_count)
: current_slot_(0), args_length_(-1), first_slot_index_(-1) { : current_slot_(0),
args_length_(-1),
first_slot_index_(-1),
should_deoptimize_(false) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
int deopt_index = Safepoint::kNoDeoptimizationIndex; int deopt_index = Safepoint::kNoDeoptimizationIndex;
...@@ -3208,7 +3211,6 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, ...@@ -3208,7 +3211,6 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
CHECK_GT(jsframe_count, inlined_jsframe_index); CHECK_GT(jsframe_count, inlined_jsframe_index);
int jsframes_to_skip = inlined_jsframe_index; int jsframes_to_skip = inlined_jsframe_index;
int number_of_slots = -1; // Number of slots inside our frame (yet unknown) int number_of_slots = -1; // Number of slots inside our frame (yet unknown)
bool should_deopt = false;
while (number_of_slots != 0) { while (number_of_slots != 0) {
opcode = static_cast<Translation::Opcode>(it.Next()); opcode = static_cast<Translation::Opcode>(it.Next());
bool processed = false; bool processed = false;
...@@ -3265,7 +3267,7 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, ...@@ -3265,7 +3267,7 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
number_of_slots += slot.GetChildrenCount(); number_of_slots += slot.GetChildrenCount();
if (slot.Representation() == SlotRef::DEFERRED_OBJECT || if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
slot.Representation() == SlotRef::DUPLICATE_OBJECT) { slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
should_deopt = true; should_deoptimize_ = true;
} }
} }
...@@ -3276,7 +3278,7 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame, ...@@ -3276,7 +3278,7 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
it.Skip(Translation::NumberOfOperandsFor(opcode)); it.Skip(Translation::NumberOfOperandsFor(opcode));
} }
} }
if (should_deopt) { if (should_deoptimize_) {
List<JSFunction*> functions(2); List<JSFunction*> functions(2);
frame->GetFunctions(&functions); frame->GetFunctions(&functions);
Deoptimizer::DeoptimizeFunction(functions[0]); Deoptimizer::DeoptimizeFunction(functions[0]);
...@@ -3492,9 +3494,11 @@ void SlotRefValueBuilder::Finish(Isolate* isolate) { ...@@ -3492,9 +3494,11 @@ void SlotRefValueBuilder::Finish(Isolate* isolate) {
// We should have processed all the slots // We should have processed all the slots
CHECK_EQ(slot_refs_.length(), current_slot_); CHECK_EQ(slot_refs_.length(), current_slot_);
if (materialized_objects_.length() > prev_materialized_count_) { if (should_deoptimize_ &&
// We have materialized some new objects, so we have to store them materialized_objects_.length() > prev_materialized_count_) {
// to prevent duplicate materialization // We have materialized some new objects and they might be accessible
// from the arguments object, so we have to store them
// to prevent duplicate materialization.
Handle<FixedArray> array = isolate->factory()->NewFixedArray( Handle<FixedArray> array = isolate->factory()->NewFixedArray(
materialized_objects_.length()); materialized_objects_.length());
for (int i = 0; i < materialized_objects_.length(); i++) { for (int i = 0; i < materialized_objects_.length(); i++) {
......
...@@ -939,6 +939,7 @@ class SlotRefValueBuilder BASE_EMBEDDED { ...@@ -939,6 +939,7 @@ class SlotRefValueBuilder BASE_EMBEDDED {
int current_slot_; int current_slot_;
int args_length_; int args_length_;
int first_slot_index_; int first_slot_index_;
bool should_deoptimize_;
static SlotRef ComputeSlotForNextArgument( static SlotRef ComputeSlotForNextArgument(
Translation::Opcode opcode, Translation::Opcode opcode,
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function f() {
return f.arguments;
}
function g(deopt) {
var o = { x : 2 };
f();
o.x = 1;
deopt + 0;
return o.x;
}
g(0);
g(0);
%OptimizeFunctionOnNextCall(g);
assertEquals(1, g({}));
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