}
+void LChunkBuilder::AddDeprecationDependency(Handle<Map> map) {
+ if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+ chunk_->AddDeprecationDependency(map);
+}
+
+
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
// We need a temporary register for write barrier of the map field.
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
+ // Add a deprecation dependency on the transition target map.
+ if (instr->has_transition()) {
+ AddDeprecationDependency(instr->transition_map());
+ }
+
LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
if (!instr->access().IsExternalMemory() &&
instr->field_representation().IsHeapObject() &&
void Abort(BailoutReason reason);
+ // Methods for code dependencies.
+ void AddDeprecationDependency(Handle<Map> map);
+
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
LUnallocated* ToUnallocated(DoubleRegister reg);
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
}
}
+void LChunkBuilder::AddDeprecationDependency(Handle<Map> map) {
+ if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+ chunk_->AddDeprecationDependency(map);
+}
+
+
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
temp0 = TempRegister();
}
+ // Add a deprecation dependency on the transition target map.
+ if (instr->has_transition()) {
+ AddDeprecationDependency(instr->transition_map());
+ }
+
LStoreNamedField* result =
new(zone()) LStoreNamedField(object, value, temp0, temp1);
if (instr->field_representation().IsHeapObject() &&
void Abort(BailoutReason reason);
+ // Methods for code dependencies.
+ void AddDeprecationDependency(Handle<Map> map);
+
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
LUnallocated* ToUnallocated(DoubleRegister reg);
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
}
}
+// Key comparison function for Map handles.
+inline bool operator<(const Handle<Map>& lhs, const Handle<Map>& rhs) {
+ // This is safe because maps don't move.
+ return *lhs < *rhs;
+}
+
+
class DeferredHandles;
class HandleScopeImplementer;
}
}
- void SetTransition(HConstant* map_constant, CompilationInfo* info) {
+ void SetTransition(HConstant* transition) {
ASSERT(!has_transition()); // Only set once.
- Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate()));
- if (map->CanBeDeprecated()) {
- Map::AddDependentCompilationInfo(
- map, DependentCode::kTransitionGroup, info);
- }
- SetOperandAt(2, map_constant);
+ SetOperandAt(2, transition);
has_transition_ = true;
}
}
if (transition_to_field) {
- HConstant* transition_constant = Add<HConstant>(info->transition());
- instr->SetTransition(transition_constant, top_info());
- instr->SetChangesFlag(kMaps);
+ Handle<Map> transition(info->transition());
+ ASSERT(!transition->is_deprecated());
+ instr->SetTransition(Add<HConstant>(transition));
}
return instr;
}
if (!info()->IsStub()) {
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
- info()->CommitDependencies(code);
}
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
- Representation representation = instr->representation();
+ Representation representation = instr->hydrogen()->field_representation();
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
}
Register object = ToRegister(instr->object());
- Handle<Map> transition = instr->transition();
SmiCheck check_needed =
instr->hydrogen()->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
}
}
} else if (representation.IsDouble()) {
- ASSERT(transition.is_null());
ASSERT(access.IsInobject());
+ ASSERT(!instr->hydrogen()->has_transition());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
return;
}
- if (!transition.is_null()) {
+ if (instr->hydrogen()->has_transition()) {
+ Handle<Map> transition = instr->hydrogen()->transition_map();
if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
__ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
} else {
}
+void LChunkBuilder::AddDeprecationDependency(Handle<Map> map) {
+ if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+ chunk_->AddDeprecationDependency(map);
+}
+
+
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
// We need a temporary register for write barrier of the map field.
LOperand* temp_map = needs_write_barrier_for_map ? TempRegister() : NULL;
+ // Add a deprecation dependency on the transition target map.
+ if (instr->has_transition()) {
+ AddDeprecationDependency(instr->transition_map());
+ }
+
LInstruction* result =
new(zone()) LStoreNamedField(obj, val, temp, temp_map);
if (!instr->access().IsExternalMemory() &&
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
- Handle<Map> transition() const { return hydrogen()->transition_map(); }
- Representation representation() const {
- return hydrogen()->field_representation();
- }
};
void Abort(BailoutReason reason);
+ // Methods for code dependencies.
+ void AddDeprecationDependency(Handle<Map> map);
+
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
LUnallocated* ToUnallocated(XMMRegister reg);
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
- inlined_closures_(1, graph->zone()) {
+ inlined_closures_(1, graph->zone()),
+ deprecation_dependencies_(MapLess(), MapAllocator(graph->zone())) {
}
}
+void LChunk::CommitDependencies(Handle<Code> code) const {
+ for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
+ iend = deprecation_dependencies_.end(); it != iend; ++it) {
+ Handle<Map> map = *it;
+ ASSERT(!map->is_deprecated());
+ ASSERT(map->CanBeDeprecated());
+ Map::AddDependentCode(map, DependentCode::kTransitionGroup, code);
+ }
+
+ info_->CommitDependencies(code);
+}
+
+
LChunk* LChunk::NewChunk(HGraph* graph) {
DisallowHandleAllocation no_handles;
DisallowHeapAllocation no_gc;
Handle<Code> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
generator.FinishCode(code);
+ CommitDependencies(code);
code->set_is_crankshafted(true);
void* jit_handler_data =
assembler.positions_recorder()->DetachJITHandlerData();
#ifndef V8_LITHIUM_H_
#define V8_LITHIUM_H_
+#include <set>
+
#include "allocation.h"
#include "hydrogen.h"
#include "safepoint-table.h"
+#include "zone-allocator.h"
namespace v8 {
namespace internal {
inlined_closures_.Add(closure, zone());
}
+ void AddDeprecationDependency(Handle<Map> map) {
+ ASSERT(!map->is_deprecated());
+ if (!map->CanBeDeprecated()) return;
+ ASSERT(!info_->IsStub());
+ deprecation_dependencies_.insert(map);
+ }
+
Zone* zone() const { return info_->zone(); }
Handle<Code> Codegen();
int spill_slot_count_;
private:
+ typedef std::less<Handle<Map> > MapLess;
+ typedef zone_allocator<Handle<Map> > MapAllocator;
+ typedef std::set<Handle<Map>, MapLess, MapAllocator> MapSet;
+
+ void CommitDependencies(Handle<Code> code) const;
+
CompilationInfo* info_;
HGraph* const graph_;
BitVector* allocated_double_registers_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
+ MapSet deprecation_dependencies_;
};
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
}
}
+void LChunkBuilder::AddDeprecationDependency(Handle<Map> map) {
+ if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+ chunk_->AddDeprecationDependency(map);
+}
+
+
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
// We need a temporary register for write barrier of the map field.
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
+ // Add a deprecation dependency on the transition target map.
+ if (instr->has_transition()) {
+ AddDeprecationDependency(instr->transition_map());
+ }
+
LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
if (!instr->access().IsExternalMemory() &&
instr->field_representation().IsHeapObject() &&
void Abort(BailoutReason reason);
+ // Methods for code dependencies.
+ void AddDeprecationDependency(Handle<Map> map);
+
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
LUnallocated* ToUnallocated(DoubleRegister reg);
V(kLiveEdit, "LiveEdit") \
V(kLookupVariableInCountOperation, \
"Lookup variable in count operation") \
+ V(kMapBecameDeprecated, "Map became deprecated") \
V(kMapIsNoLongerInEax, "Map is no longer in eax") \
V(kModuleDeclaration, "Module declaration") \
V(kModuleLiteral, "Module literal") \
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
}
}
+void LChunkBuilder::AddDeprecationDependency(Handle<Map> map) {
+ if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+ chunk_->AddDeprecationDependency(map);
+}
+
+
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
LOperand* temp = (!is_in_object || needs_write_barrier ||
needs_write_barrier_for_map) ? TempRegister() : NULL;
+ // Add a deprecation dependency on the transition target map.
+ if (instr->has_transition()) {
+ AddDeprecationDependency(instr->transition_map());
+ }
+
LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
if (!instr->access().IsExternalMemory() &&
instr->field_representation().IsHeapObject() &&
void Abort(BailoutReason reason);
+ // Methods for code dependencies.
+ void AddDeprecationDependency(Handle<Map> map);
+
// Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg);
LUnallocated* ToUnallocated(XMMRegister reg);