MIPS: Migrate instance of deprecated maps in HCheckMaps.

Port r16057 (b73ae514)

Original commit message:
Currently only direct map checks are supported. Otherwise only polymorphic cases with a generic fallback behave properly, regular polymorphic cases still need to be adapted.

BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16062 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
palfia@homejinni.com 2013-08-06 01:12:10 +00:00
parent fe7df8c703
commit 8575ae5530
3 changed files with 52 additions and 14 deletions

View File

@ -5193,31 +5193,63 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
}
void LCodeGen::DoCheckMapCommon(Register map_reg,
Handle<Map> map,
LEnvironment* env) {
Label success;
__ CompareMapAndBranch(map_reg, map, &success, eq, &success);
DeoptimizeIf(al, env);
__ bind(&success);
void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
{
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
__ push(object);
CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
__ StoreToSafepointRegisterSlot(v0, scratch0());
}
__ And(at, scratch0(), Operand(kSmiTagMask));
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
}
void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
class DeferredCheckMaps: public LDeferredCode {
public:
DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
: LDeferredCode(codegen), instr_(instr), object_(object) {
SetExit(check_maps());
}
virtual void Generate() {
codegen()->DoDeferredInstanceMigration(instr_, object_);
}
Label* check_maps() { return &check_maps_; }
virtual LInstruction* instr() { return instr_; }
private:
LCheckMaps* instr_;
Label check_maps_;
Register object_;
};
if (instr->hydrogen()->CanOmitMapChecks()) return;
Register map_reg = scratch0();
LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
Label success;
SmallMapList* map_set = instr->hydrogen()->map_set();
__ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
DeferredCheckMaps* deferred = NULL;
if (instr->hydrogen()->has_migration_target()) {
deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
__ bind(deferred->check_maps());
}
Label success;
for (int i = 0; i < map_set->length() - 1; i++) {
Handle<Map> map = map_set->at(i);
__ CompareMapAndBranch(map_reg, map, &success, eq, &success);
}
Handle<Map> map = map_set->last();
DoCheckMapCommon(map_reg, map, instr->environment());
__ CompareMapAndBranch(map_reg, map, &success, eq, &success);
if (instr->hydrogen()->has_migration_target()) {
__ Branch(deferred->entry());
} else {
DeoptimizeIf(al, instr->environment());
}
__ bind(&success);
}

View File

@ -153,7 +153,7 @@ class LCodeGen BASE_EMBEDDED {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
void DoCheckMapCommon(Register map_reg, Handle<Map> map, LEnvironment* env);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
// Parallel move support.
void DoParallelMove(LParallelMove* move);

View File

@ -1934,10 +1934,16 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
LOperand* value = NULL;
if (!instr->CanOmitMapChecks()) value = UseRegisterAtStart(instr->value());
LInstruction* result = new(zone()) LCheckMaps(value);
if (instr->CanOmitMapChecks()) return result;
return AssignEnvironment(result);
if (!instr->CanOmitMapChecks()) {
value = UseRegisterAtStart(instr->value());
if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
}
LCheckMaps* result = new(zone()) LCheckMaps(value);
if (!instr->CanOmitMapChecks()) {
AssignEnvironment(result);
if (instr->has_migration_target()) return AssignPointerMap(result);
}
return result;
}