Revision: 16403
Author: [email protected]
Date: Wed Aug 28 14:16:57 2013 UTC
Log: Implement proper map checks of captured objects.
[email protected]
TEST=mjsunit/compiler/escape-analysis
Review URL: https://codereview.chromium.org/23697002
http://code.google.com/p/v8/source/detail?r=16403
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/hydrogen-escape-analysis.cc
/branches/bleeding_edge/src/hydrogen-escape-analysis.h
/branches/bleeding_edge/src/hydrogen-instructions.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/mips/lithium-mips.cc
/branches/bleeding_edge/src/mips/lithium-mips.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
/branches/bleeding_edge/test/mjsunit/compiler/escape-analysis.js
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Aug 27 14:02:08 2013
UTC
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Aug 28 14:16:57 2013
UTC
@@ -2027,9 +2027,9 @@
}
-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckFunction(value));
+ return AssignEnvironment(new(zone()) LCheckValue(value));
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue Aug 27 11:55:08 2013
UTC
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Aug 28 14:16:57 2013
UTC
@@ -62,12 +62,12 @@
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
- V(CheckFunction) \
V(CheckInstanceType) \
V(CheckNonSmi) \
V(CheckMaps) \
V(CheckMapValue) \
V(CheckSmi) \
+ V(CheckValue) \
V(ClampDToUint8) \
V(ClampIToUint8) \
V(ClampTToUint8) \
@@ -2338,16 +2338,16 @@
};
-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckFunction(LOperand* value) {
+ explicit LCheckValue(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
- DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+ DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+ DECLARE_HYDROGEN_ACCESSOR(CheckValue)
};
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Aug 27
13:55:00 2013 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Aug 28
14:16:57 2013 UTC
@@ -5131,18 +5131,18 @@
}
-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
Register reg = ToRegister(instr->value());
- Handle<JSFunction> target = instr->hydrogen()->target();
+ Handle<HeapObject> object = instr->hydrogen()->object();
AllowDeferredHandleDereference smi_check;
- if (isolate()->heap()->InNewSpace(*target)) {
+ if (isolate()->heap()->InNewSpace(*object)) {
Register reg = ToRegister(instr->value());
- Handle<Cell> cell = isolate()->factory()->NewCell(target);
+ Handle<Cell> cell = isolate()->factory()->NewCell(object);
__ mov(ip, Operand(Handle<Object>(cell)));
__ ldr(ip, FieldMemOperand(ip, Cell::kValueOffset));
__ cmp(reg, ip);
} else {
- __ cmp(reg, Operand(target));
+ __ cmp(reg, Operand(object));
}
DeoptimizeIf(ne, instr->environment());
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Wed Aug 28
12:36:32 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Wed Aug 28
14:16:57 2013 UTC
@@ -86,7 +86,8 @@
// Create a new state full of phis for loop header entries.
HCapturedObject* HEscapeAnalysisPhase::NewStateForLoopHeader(
- HInstruction* previous, HCapturedObject* old_state) {
+ HInstruction* previous,
+ HCapturedObject* old_state) {
HBasicBlock* block = previous->block();
HCapturedObject* state = NewState(previous);
for (int index = 0; index < number_of_values_; index++) {
@@ -100,7 +101,8 @@
// Create a new state by copying an existing one.
HCapturedObject* HEscapeAnalysisPhase::NewStateCopy(
- HInstruction* previous, HCapturedObject* old_state) {
+ HInstruction* previous,
+ HCapturedObject* old_state) {
HCapturedObject* state = NewState(previous);
for (int index = 0; index < number_of_values_; index++) {
HValue* operand = old_state->OperandAt(index);
@@ -112,8 +114,9 @@
// Insert a newly created phi into the given block and fill all incoming
// edges with the given value.
-HPhi* HEscapeAnalysisPhase::NewPhiAndInsert(
- HBasicBlock* block, HValue* incoming_value, int index) {
+HPhi* HEscapeAnalysisPhase::NewPhiAndInsert(HBasicBlock* block,
+ HValue* incoming_value,
+ int index) {
Zone* zone = graph()->zone();
HPhi* phi = new(zone) HPhi(HPhi::kInvalidMergedIndex, zone);
for (int i = 0; i < block->predecessors()->length(); i++) {
@@ -122,6 +125,21 @@
block->AddPhi(phi);
return phi;
}
+
+
+// Insert a newly created value check as a replacement for map checks.
+HValue* HEscapeAnalysisPhase::NewMapCheckAndInsert(HCapturedObject* state,
+ HCheckMaps* mapcheck) {
+ Zone* zone = graph()->zone();
+ HValue* value = state->map_value();
+ // TODO(mstarzinger): This will narrow a map check against a set of maps
+ // down to the first element in the set. Revisit and fix this.
+ Handle<Map> map_object = mapcheck->map_set()->first();
+ UniqueValueId map_id = mapcheck->map_unique_ids()->first();
+ HCheckValue* check = HCheckValue::New(zone, NULL, value, map_object,
map_id);
+ check->InsertBefore(mapcheck);
+ return check;
+}
// Performs a forward data-flow analysis of all loads and stores on the
@@ -180,7 +198,7 @@
if (store->HasObservableSideEffects()) {
state->ReuseSideEffectsFromStore(store);
}
- store->DeleteAndReplaceWith(NULL);
+ store->DeleteAndReplaceWith(store->ActualValue());
if (FLAG_trace_escape_analysis) {
PrintF("Replacing store #%d%s\n", instr->id(),
store->has_transition() ? " (with transition)" : "");
@@ -199,15 +217,13 @@
case HValue::kCheckHeapObject: {
HCheckHeapObject* check = HCheckHeapObject::cast(instr);
if (check->value() != allocate) continue;
- check->DeleteAndReplaceWith(NULL);
+ check->DeleteAndReplaceWith(check->ActualValue());
break;
}
case HValue::kCheckMaps: {
HCheckMaps* mapcheck = HCheckMaps::cast(instr);
if (mapcheck->value() != allocate) continue;
- // TODO(mstarzinger): This approach breaks if the tracked map
value
- // is not a HConstant. Find a repro test case and fix this.
- ASSERT(mapcheck->ActualValue() == allocate);
+ NewMapCheckAndInsert(state, mapcheck);
mapcheck->DeleteAndReplaceWith(mapcheck->ActualValue());
break;
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.h Mon Aug 26
16:43:19 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-escape-analysis.h Wed Aug 28
14:16:57 2013 UTC
@@ -63,6 +63,8 @@
HPhi* NewPhiAndInsert(HBasicBlock* block, HValue* incoming_value, int
index);
+ HValue* NewMapCheckAndInsert(HCapturedObject* state, HCheckMaps*
mapcheck);
+
HCapturedObject* StateAt(HBasicBlock* block) {
return block_states_.at(block->block_id());
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 28
12:35:07 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 28
14:16:57 2013 UTC
@@ -1451,15 +1451,16 @@
}
-void HCheckFunction::PrintDataTo(StringStream* stream) {
+void HCheckValue::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
- stream->Add(" %p", *target());
+ stream->Add(" ");
+ object()->ShortPrint(stream);
}
-HValue* HCheckFunction::Canonicalize() {
+HValue* HCheckValue::Canonicalize() {
return (value()->IsConstant() &&
- HConstant::cast(value())->UniqueValueIdsMatch(target_unique_id_))
+ HConstant::cast(value())->UniqueValueIdsMatch(object_unique_id_))
? NULL
: this;
}
@@ -4052,7 +4053,7 @@
}
-void HCheckFunction::Verify() {
+void HCheckValue::Verify() {
HInstruction::Verify();
ASSERT(HasNoUses());
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 28 12:36:32
2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 28 14:16:57
2013 UTC
@@ -88,12 +88,12 @@
V(CallStub) \
V(CapturedObject) \
V(Change) \
- V(CheckFunction) \
V(CheckHeapObject) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
V(CheckSmi) \
+ V(CheckValue) \
V(ClampToUint8) \
V(ClassOfTestAndBranch) \
V(CompareNumericAndBranch) \
@@ -2562,6 +2562,7 @@
HValue* value() { return OperandAt(0); }
SmallMapList* map_set() { return &map_set_; }
+ ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; }
bool has_migration_target() {
return has_migration_target_;
@@ -2630,9 +2631,20 @@
};
-class HCheckFunction V8_FINAL : public HUnaryOperation {
+class HCheckValue V8_FINAL : public HUnaryOperation {
public:
- DECLARE_INSTRUCTION_FACTORY_P2(HCheckFunction, HValue*,
Handle<JSFunction>);
+ static HCheckValue* New(Zone* zone, HValue* context,
+ HValue* value, Handle<JSFunction> target) {
+ bool in_new_space = Isolate::Current()->heap()->InNewSpace(*target);
+ HCheckValue* check = new(zone) HCheckValue(value, target,
in_new_space);
+ return check;
+ }
+ static HCheckValue* New(Zone* zone, HValue* context,
+ HValue* value, Handle<Map> map, UniqueValueId
id) {
+ HCheckValue* check = new(zone) HCheckValue(value, map, false);
+ check->object_unique_id_ = id;
+ return check;
+ }
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
@@ -2646,32 +2658,31 @@
#endif
virtual void FinalizeUniqueValueId() V8_OVERRIDE {
- target_unique_id_ = UniqueValueId(target_);
+ object_unique_id_ = UniqueValueId(object_);
}
- Handle<JSFunction> target() const { return target_; }
- bool target_in_new_space() const { return target_in_new_space_; }
+ Handle<HeapObject> object() const { return object_; }
+ bool object_in_new_space() const { return object_in_new_space_; }
- DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
+ DECLARE_CONCRETE_INSTRUCTION(CheckValue)
protected:
virtual bool DataEquals(HValue* other) V8_OVERRIDE {
- HCheckFunction* b = HCheckFunction::cast(other);
- return target_unique_id_ == b->target_unique_id_;
+ HCheckValue* b = HCheckValue::cast(other);
+ return object_unique_id_ == b->object_unique_id_;
}
private:
- HCheckFunction(HValue* value, Handle<JSFunction> function)
+ HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space)
: HUnaryOperation(value, value->type()),
- target_(function), target_unique_id_() {
+ object_(object), object_in_new_space_(in_new_space) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
- target_in_new_space_ =
Isolate::Current()->heap()->InNewSpace(*function);
}
- Handle<JSFunction> target_;
- UniqueValueId target_unique_id_;
- bool target_in_new_space_;
+ Handle<HeapObject> object_;
+ UniqueValueId object_unique_id_;
+ bool object_in_new_space_;
};
@@ -3229,6 +3240,9 @@
const ZoneList<HValue*>* values() const { return &values_; }
int length() const { return values_.length(); }
int capture_id() const { return capture_id_; }
+
+ // Shortcut for the map value of this captured object.
+ HValue* map_value() const { return values()->first(); }
void ReuseSideEffectsFromStore(HInstruction* store) {
ASSERT(store->HasObservableSideEffects());
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Wed Aug 28 13:03:06 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Aug 28 14:16:57 2013 UTC
@@ -7110,7 +7110,7 @@
CHECK_ALIVE(VisitForValue(expr->expression()));
HValue* function = Pop();
- Add<HCheckFunction>(function, expr->target());
+ Add<HCheckValue>(function, expr->target());
// Replace the global object with the global receiver.
HGlobalReceiver* global_receiver =
Add<HGlobalReceiver>(global_object);
@@ -7162,7 +7162,7 @@
HGlobalReceiver* receiver = New<HGlobalReceiver>(global);
PushAndAdd(receiver);
CHECK_ALIVE(VisitExpressions(expr->arguments()));
- Add<HCheckFunction>(function, expr->target());
+ Add<HCheckValue>(function, expr->target());
if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the
function.
if (FLAG_trace_inlining) {
@@ -7225,7 +7225,7 @@
HValue* function = Top();
CHECK_ALIVE(VisitExpressions(expr->arguments()));
Handle<JSFunction> constructor = expr->target();
- HValue* check = Add<HCheckFunction>(function, constructor);
+ HValue* check = Add<HCheckValue>(function, constructor);
// Force completion of inobject slack tracking before generating
// allocation code to finalize instance size.
@@ -7317,7 +7317,7 @@
HBinaryCall* call;
if (expr->target().is_identical_to(array_function)) {
Handle<Cell> cell = expr->allocation_info_cell();
- Add<HCheckFunction>(constructor, array_function);
+ Add<HCheckValue>(constructor, array_function);
call = new(zone()) HCallNewArray(context, constructor,
argument_count,
cell, expr->elements_kind());
} else {
@@ -8149,7 +8149,7 @@
result->set_position(expr->position());
return ast_context()->ReturnInstruction(result, expr->id());
} else {
- Add<HCheckFunction>(right, target);
+ Add<HCheckValue>(right, target);
HInstanceOfKnownGlobal* result =
new(zone()) HInstanceOfKnownGlobal(context, left, target);
result->set_position(expr->position());
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Aug 27
11:55:08 2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Aug 28
14:16:57 2013 UTC
@@ -5800,15 +5800,15 @@
}
-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
- Handle<JSFunction> target = instr->hydrogen()->target();
- if (instr->hydrogen()->target_in_new_space()) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
+ Handle<HeapObject> object = instr->hydrogen()->object();
+ if (instr->hydrogen()->object_in_new_space()) {
Register reg = ToRegister(instr->value());
- Handle<Cell> cell = isolate()->factory()->NewCell(target);
+ Handle<Cell> cell = isolate()->factory()->NewCell(object);
__ cmp(reg, Operand::ForCell(cell));
} else {
Operand operand = ToOperand(instr->value());
- __ cmp(operand, target);
+ __ cmp(operand, object);
}
DeoptimizeIf(not_equal, instr->environment());
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Aug 27 14:02:08
2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Aug 28 14:16:57
2013 UTC
@@ -2060,14 +2060,14 @@
}
-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
- // If the target is in new space, we'll emit a global cell compare and so
- // want the value in a register. If the target gets promoted before we
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
+ // If the object is in new space, we'll emit a global cell compare and so
+ // want the value in a register. If the object gets promoted before we
// emit code, we will still get the register but will do an immediate
// compare instead of the cell compare. This is safe.
- LOperand* value = instr->target_in_new_space()
+ LOperand* value = instr->object_in_new_space()
? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckFunction(value));
+ return AssignEnvironment(new(zone()) LCheckValue(value));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Aug 27 11:55:08
2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Aug 28 14:16:57
2013 UTC
@@ -62,12 +62,12 @@
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
- V(CheckFunction) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
V(CheckNonSmi) \
V(CheckSmi) \
+ V(CheckValue) \
V(ClampDToUint8) \
V(ClampIToUint8) \
V(ClampTToUint8) \
@@ -2437,16 +2437,16 @@
};
-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckFunction(LOperand* value) {
+ explicit LCheckValue(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
- DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+ DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+ DECLARE_HYDROGEN_ACCESSOR(CheckValue)
};
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Aug 27
23:05:07 2013 UTC
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Aug 28
14:16:57 2013 UTC
@@ -5116,20 +5116,20 @@
}
-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
Register reg = ToRegister(instr->value());
- Handle<JSFunction> target = instr->hydrogen()->target();
+ Handle<HeapObject> object = instr->hydrogen()->object();
AllowDeferredHandleDereference smi_check;
- if (isolate()->heap()->InNewSpace(*target)) {
+ if (isolate()->heap()->InNewSpace(*object)) {
Register reg = ToRegister(instr->value());
- Handle<Cell> cell = isolate()->factory()->NewCell(target);
+ Handle<Cell> cell = isolate()->factory()->NewCell(object);
__ li(at, Operand(Handle<Object>(cell)));
__ lw(at, FieldMemOperand(at, Cell::kValueOffset));
DeoptimizeIf(ne, instr->environment(), reg,
Operand(at));
} else {
DeoptimizeIf(ne, instr->environment(), reg,
- Operand(target));
+ Operand(object));
}
}
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Tue Aug 27 23:07:03
2013 UTC
+++ /branches/bleeding_edge/src/mips/lithium-mips.cc Wed Aug 28 14:16:57
2013 UTC
@@ -1951,9 +1951,9 @@
}
-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckFunction(value));
+ return AssignEnvironment(new(zone()) LCheckValue(value));
}
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h Tue Aug 27 22:53:25
2013 UTC
+++ /branches/bleeding_edge/src/mips/lithium-mips.h Wed Aug 28 14:16:57
2013 UTC
@@ -62,12 +62,12 @@
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
- V(CheckFunction) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
V(CheckNonSmi) \
V(CheckSmi) \
+ V(CheckValue) \
V(ClampDToUint8) \
V(ClampIToUint8) \
V(ClampTToUint8) \
@@ -2321,16 +2321,16 @@
};
-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckFunction(LOperand* value) {
+ explicit LCheckValue(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
- DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+ DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+ DECLARE_HYDROGEN_ACCESSOR(CheckValue)
};
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Aug 27
13:55:00 2013 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Aug 28
14:16:57 2013 UTC
@@ -4915,10 +4915,10 @@
}
-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
Register reg = ToRegister(instr->value());
- Handle<JSFunction> target = instr->hydrogen()->target();
- __ CmpHeapObject(reg, target);
+ Handle<HeapObject> object = instr->hydrogen()->object();
+ __ CmpHeapObject(reg, object);
DeoptimizeIf(not_equal, instr->environment());
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Aug 27 14:02:08 2013
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Aug 28 14:16:57 2013
UTC
@@ -1940,9 +1940,9 @@
}
-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckFunction(value));
+ return AssignEnvironment(new(zone()) LCheckValue(value));
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Aug 27 11:55:08 2013
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Aug 28 14:16:57 2013
UTC
@@ -62,12 +62,12 @@
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
- V(CheckFunction) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
V(CheckNonSmi) \
V(CheckSmi) \
+ V(CheckValue) \
V(ClampDToUint8) \
V(ClampIToUint8) \
V(ClampTToUint8) \
@@ -2260,16 +2260,16 @@
};
-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckFunction(LOperand* value) {
+ explicit LCheckValue(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
- DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+ DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+ DECLARE_HYDROGEN_ACCESSOR(CheckValue)
};
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/escape-analysis.js Mon
Aug 26 16:43:19 2013 UTC
+++ /branches/bleeding_edge/test/mjsunit/compiler/escape-analysis.js Wed
Aug 28 14:16:57 2013 UTC
@@ -173,3 +173,30 @@
delete deopt.deopt;
func(); func();
})();
+
+
+// Test map checks on captured objects.
+(function testMapCheck() {
+ var sum = 0;
+ function getter() { return 27; }
+ function setter(v) { sum += v; }
+ function constructor() {
+ this.x = 23;
+ this.y = 42;
+ }
+ function check(x, y) {
+ var o = new constructor();
+ assertEquals(x, o.x);
+ assertEquals(y, o.y);
+ }
+ var monkey = Object.create(null, {
+ x: { get:getter, set:setter },
+ y: { get:getter, set:setter }
+ });
+ check(23, 42); check(23, 42);
+ %OptimizeFunctionOnNextCall(check);
+ check(23, 42); check(23, 42);
+ constructor.prototype = monkey;
+ check(27, 27); check(27, 27);
+ assertEquals(130, sum);
+})();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.