Revert r15419: "Generate StoreGlobal stubs with Hydrogen"
TBR=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/18357004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15427 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
91dc6dd632
commit
77c20c30a3
@ -226,17 +226,6 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
|
||||
}
|
||||
|
||||
|
||||
void StoreGlobalStub::InitializeInterfaceDescriptor(
|
||||
Isolate* isolate,
|
||||
CodeStubInterfaceDescriptor* descriptor) {
|
||||
static Register registers[] = { r1, r2, r0 };
|
||||
descriptor->register_param_count_ = 3;
|
||||
descriptor->register_params_ = registers;
|
||||
descriptor->deoptimization_handler_ =
|
||||
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm,
|
||||
|
@ -219,6 +219,7 @@ void LGapResolver::EmitMove(int index) {
|
||||
ASSERT(destination->IsStackSlot());
|
||||
__ str(source_register, cgen_->ToMemOperand(destination));
|
||||
}
|
||||
|
||||
} else if (source->IsStackSlot()) {
|
||||
MemOperand source_operand = cgen_->ToMemOperand(source);
|
||||
if (destination->IsRegister()) {
|
||||
@ -254,10 +255,6 @@ void LGapResolver::EmitMove(int index) {
|
||||
} else {
|
||||
__ LoadObject(dst, cgen_->ToHandle(constant_source));
|
||||
}
|
||||
} else if (source->IsDoubleRegister()) {
|
||||
DwVfpRegister result = cgen_->ToDoubleRegister(destination);
|
||||
double v = cgen_->ToDouble(constant_source);
|
||||
__ Vmov(result, v, ip);
|
||||
} else {
|
||||
ASSERT(destination->IsStackSlot());
|
||||
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone.
|
||||
|
@ -675,7 +675,6 @@ void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||
if (is_monomorphic_) {
|
||||
target_ = oracle->GetCallNewTarget(this);
|
||||
Object* value = allocation_info_cell_->value();
|
||||
ASSERT(!value->IsTheHole());
|
||||
if (value->IsSmi()) {
|
||||
elements_kind_ = static_cast<ElementsKind>(Smi::cast(value)->value());
|
||||
}
|
||||
|
@ -771,7 +771,7 @@ HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() {
|
||||
IfBuilder if_true(this);
|
||||
if_true.If<HBranch>(GetParameter(0), stub->GetTypes());
|
||||
if_true.Then();
|
||||
if_true.Return(graph()->GetConstant1());
|
||||
if_true.Return(graph()->GetConstant1());
|
||||
if_true.Else();
|
||||
if_true.End();
|
||||
return graph()->GetConstant0();
|
||||
@ -783,49 +783,4 @@ Handle<Code> ToBooleanStub::GenerateCode() {
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
|
||||
StoreGlobalStub* stub = casted_stub();
|
||||
Handle<Object> hole(isolate()->heap()->the_hole_value(), isolate());
|
||||
Handle<Object> placeholer_value(Smi::FromInt(0), isolate());
|
||||
Handle<PropertyCell> placeholder_cell =
|
||||
isolate()->factory()->NewPropertyCell(placeholer_value);
|
||||
|
||||
HParameter* receiver = GetParameter(0);
|
||||
HParameter* value = GetParameter(2);
|
||||
|
||||
if (stub->is_constant()) {
|
||||
// Assume every store to a constant value changes it.
|
||||
current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
|
||||
set_current_block(NULL);
|
||||
} else {
|
||||
HValue* cell = Add<HConstant>(placeholder_cell, Representation::Tagged());
|
||||
// Check that the map of the global has not changed.
|
||||
AddInstruction(HCheckMaps::New(receiver,
|
||||
Handle<Map>(isolate()->heap()->meta_map()),
|
||||
zone()));
|
||||
|
||||
// Load the payload of the global parameter cell. A hole indicates that the
|
||||
// property has been deleted and that the store must be handled by the
|
||||
// runtime.
|
||||
HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
|
||||
HValue* cell_contents = Add<HLoadNamedField>(cell, access);
|
||||
IfBuilder builder(this);
|
||||
HValue* hole_value = Add<HConstant>(hole, Representation::Tagged());
|
||||
builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
|
||||
builder.Then();
|
||||
builder.Deopt();
|
||||
builder.Else();
|
||||
Add<HStoreNamedField>(cell, access, value);
|
||||
builder.End();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> StoreGlobalStub::GenerateCode() {
|
||||
return DoGenerateCode(this);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -84,14 +84,6 @@ Code::Kind CodeStub::GetCodeKind() const {
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> CodeStub::GetCodeCopyFromTemplate(Isolate* isolate) {
|
||||
Handle<Code> ic = GetCode(isolate);
|
||||
ic = isolate->factory()->CopyCode(ic);
|
||||
RecordCodeGeneration(*ic, isolate);
|
||||
return ic;
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> PlatformCodeStub::GenerateCode() {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
Factory* factory = isolate->factory();
|
||||
|
@ -90,7 +90,6 @@ namespace internal {
|
||||
V(ArrayConstructor) \
|
||||
V(InternalArrayConstructor) \
|
||||
V(ProfileEntryHook) \
|
||||
V(StoreGlobal) \
|
||||
/* IC Handler stubs */ \
|
||||
V(LoadField) \
|
||||
V(KeyedLoadField)
|
||||
@ -141,8 +140,6 @@ class CodeStub BASE_EMBEDDED {
|
||||
// Retrieve the code for the stub. Generate the code if needed.
|
||||
Handle<Code> GetCode(Isolate* isolate);
|
||||
|
||||
// Retrieve the code for the stub, make and return a copy of the code.
|
||||
Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate);
|
||||
static Major MajorKeyFromKey(uint32_t key) {
|
||||
return static_cast<Major>(MajorKeyBits::decode(key));
|
||||
}
|
||||
@ -522,50 +519,6 @@ class FastNewBlockContextStub : public PlatformCodeStub {
|
||||
int MinorKey() { return slots_; }
|
||||
};
|
||||
|
||||
class StoreGlobalStub : public HydrogenCodeStub {
|
||||
public:
|
||||
StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) {
|
||||
bit_field_ = StrictModeBits::encode(strict_mode) |
|
||||
IsConstantBits::encode(is_constant);
|
||||
}
|
||||
|
||||
virtual Handle<Code> GenerateCode();
|
||||
|
||||
virtual void InitializeInterfaceDescriptor(
|
||||
Isolate* isolate,
|
||||
CodeStubInterfaceDescriptor* descriptor);
|
||||
|
||||
virtual Code::Kind GetCodeKind() const { return Code::STORE_IC; }
|
||||
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
|
||||
virtual Code::ExtraICState GetExtraICState() { return bit_field_; }
|
||||
|
||||
bool is_constant() {
|
||||
return IsConstantBits::decode(bit_field_);
|
||||
}
|
||||
void set_is_constant(bool value) {
|
||||
bit_field_ = IsConstantBits::update(bit_field_, value);
|
||||
}
|
||||
|
||||
Representation representation() {
|
||||
return Representation::FromKind(RepresentationBits::decode(bit_field_));
|
||||
}
|
||||
void set_representation(Representation r) {
|
||||
bit_field_ = RepresentationBits::update(bit_field_, r.kind());
|
||||
}
|
||||
|
||||
private:
|
||||
virtual int NotMissMinorKey() { return GetExtraICState(); }
|
||||
Major MajorKey() { return StoreGlobal; }
|
||||
|
||||
class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {};
|
||||
class IsConstantBits: public BitField<bool, 1, 1> {};
|
||||
class RepresentationBits: public BitField<Representation::Kind, 2, 8> {};
|
||||
|
||||
int bit_field_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
|
||||
};
|
||||
|
||||
|
||||
class FastCloneShallowArrayStub : public HydrogenCodeStub {
|
||||
public:
|
||||
|
@ -2864,7 +2864,6 @@ MaybeObject* Heap::AllocatePropertyCell(Object* value) {
|
||||
SKIP_WRITE_BARRIER);
|
||||
cell->set_value(value);
|
||||
cell->set_type(Type::None());
|
||||
cell->SetValueInferType(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,6 @@ namespace internal {
|
||||
V(map_field_string, "%map") \
|
||||
V(elements_field_string, "%elements") \
|
||||
V(length_field_string, "%length") \
|
||||
V(cell_value_string, "%cell_value") \
|
||||
V(function_class_string, "Function") \
|
||||
V(properties_field_symbol, "%properties") \
|
||||
V(payload_field_symbol, "%payload") \
|
||||
|
@ -2174,7 +2174,6 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
|
||||
has_double_value_(false),
|
||||
is_internalized_string_(false),
|
||||
is_not_in_new_space_(true),
|
||||
is_cell_(false),
|
||||
boolean_value_(handle->BooleanValue()) {
|
||||
if (handle_->IsHeapObject()) {
|
||||
Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap();
|
||||
@ -2191,9 +2190,6 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
|
||||
type_from_value_ = HType::TypeFromValue(handle_);
|
||||
is_internalized_string_ = handle_->IsInternalizedString();
|
||||
}
|
||||
|
||||
is_cell_ = !handle_.is_null() &&
|
||||
(handle_->IsCell() || handle_->IsPropertyCell());
|
||||
Initialize(r);
|
||||
}
|
||||
|
||||
@ -2204,7 +2200,6 @@ HConstant::HConstant(Handle<Object> handle,
|
||||
HType type,
|
||||
bool is_internalize_string,
|
||||
bool is_not_in_new_space,
|
||||
bool is_cell,
|
||||
bool boolean_value)
|
||||
: handle_(handle),
|
||||
unique_id_(unique_id),
|
||||
@ -2213,7 +2208,6 @@ HConstant::HConstant(Handle<Object> handle,
|
||||
has_double_value_(false),
|
||||
is_internalized_string_(is_internalize_string),
|
||||
is_not_in_new_space_(is_not_in_new_space),
|
||||
is_cell_(is_cell),
|
||||
boolean_value_(boolean_value),
|
||||
type_from_value_(type) {
|
||||
ASSERT(!handle.is_null());
|
||||
@ -2233,7 +2227,6 @@ HConstant::HConstant(int32_t integer_value,
|
||||
has_double_value_(true),
|
||||
is_internalized_string_(false),
|
||||
is_not_in_new_space_(is_not_in_new_space),
|
||||
is_cell_(false),
|
||||
boolean_value_(integer_value != 0),
|
||||
int32_value_(integer_value),
|
||||
double_value_(FastI2D(integer_value)) {
|
||||
@ -2252,7 +2245,6 @@ HConstant::HConstant(double double_value,
|
||||
has_double_value_(true),
|
||||
is_internalized_string_(false),
|
||||
is_not_in_new_space_(is_not_in_new_space),
|
||||
is_cell_(false),
|
||||
boolean_value_(double_value != 0 && !std::isnan(double_value)),
|
||||
int32_value_(DoubleToInt32(double_value)),
|
||||
double_value_(double_value) {
|
||||
@ -2275,17 +2267,9 @@ void HConstant::Initialize(Representation r) {
|
||||
}
|
||||
set_representation(r);
|
||||
SetFlag(kUseGVN);
|
||||
}
|
||||
|
||||
|
||||
bool HConstant::EmitAtUses() {
|
||||
ASSERT(IsLinked());
|
||||
if (block()->graph()->has_osr_loop_entry()) {
|
||||
return block()->graph()->IsStandardConstant(this);
|
||||
if (representation().IsInteger32()) {
|
||||
ClearGVNFlag(kDependsOnOsrEntries);
|
||||
}
|
||||
if (IsCell()) return false;
|
||||
if (representation().IsDouble()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -2306,7 +2290,6 @@ HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
|
||||
type_from_value_,
|
||||
is_internalized_string_,
|
||||
is_not_in_new_space_,
|
||||
is_cell_,
|
||||
boolean_value_);
|
||||
}
|
||||
|
||||
@ -3841,13 +3824,6 @@ HObjectAccess HObjectAccess::ForField(Handle<Map> map,
|
||||
}
|
||||
|
||||
|
||||
HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) {
|
||||
return HObjectAccess(
|
||||
kInobject, Cell::kValueOffset,
|
||||
Handle<String>(isolate->heap()->cell_value_string()));
|
||||
}
|
||||
|
||||
|
||||
void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) {
|
||||
// set the appropriate GVN flags for a given load or store instruction
|
||||
if (is_store) {
|
||||
|
@ -3270,7 +3270,6 @@ class HConstant: public HTemplateInstruction<0> {
|
||||
HType type,
|
||||
bool is_internalized_string,
|
||||
bool is_not_in_new_space,
|
||||
bool is_cell,
|
||||
bool boolean_value);
|
||||
|
||||
Handle<Object> handle() {
|
||||
@ -3319,10 +3318,6 @@ class HConstant: public HTemplateInstruction<0> {
|
||||
unique_id_ == UniqueValueId(heap->empty_string());
|
||||
}
|
||||
|
||||
bool IsCell() const {
|
||||
return is_cell_;
|
||||
}
|
||||
|
||||
virtual Representation RequiredInputRepresentation(int index) {
|
||||
return Representation::None();
|
||||
}
|
||||
@ -3334,7 +3329,7 @@ class HConstant: public HTemplateInstruction<0> {
|
||||
return Representation::Tagged();
|
||||
}
|
||||
|
||||
virtual bool EmitAtUses();
|
||||
virtual bool EmitAtUses() { return !representation().IsDouble(); }
|
||||
virtual void PrintDataTo(StringStream* stream);
|
||||
virtual HType CalculateInferredType();
|
||||
bool IsInteger() { return handle()->IsSmi(); }
|
||||
@ -3449,7 +3444,6 @@ class HConstant: public HTemplateInstruction<0> {
|
||||
bool has_double_value_ : 1;
|
||||
bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
|
||||
bool is_not_in_new_space_ : 1;
|
||||
bool is_cell_ : 1;
|
||||
bool boolean_value_ : 1;
|
||||
int32_t int32_value_;
|
||||
double double_value_;
|
||||
@ -5102,9 +5096,6 @@ inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
|
||||
HInnerAllocatedObject::cast(object)->base_object(),
|
||||
new_space_dominator);
|
||||
}
|
||||
if (object->IsConstant() && HConstant::cast(object)->IsCell()) {
|
||||
return false;
|
||||
}
|
||||
if (object != new_space_dominator) return true;
|
||||
if (object->IsAllocateObject()) return false;
|
||||
if (object->IsAllocate()) {
|
||||
@ -5366,9 +5357,6 @@ class HObjectAccess {
|
||||
static HObjectAccess ForField(Handle<Map> map,
|
||||
LookupResult *lookup, Handle<String> name = Handle<String>::null());
|
||||
|
||||
// Create an access for the payload of a Cell or JSGlobalPropertyCell.
|
||||
static HObjectAccess ForCellPayload(Isolate* isolate);
|
||||
|
||||
void PrintTo(StringStream* stream);
|
||||
|
||||
inline bool Equals(HObjectAccess that) const {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
@ -646,7 +646,6 @@ HConstant* HGraph::GetConstant##Name() { \
|
||||
htype, \
|
||||
false, \
|
||||
true, \
|
||||
false, \
|
||||
boolean_value); \
|
||||
constant->InsertAfter(GetConstantUndefined()); \
|
||||
constant_##name##_.set(constant); \
|
||||
@ -669,19 +668,6 @@ HConstant* HGraph::GetInvalidContext() {
|
||||
}
|
||||
|
||||
|
||||
bool HGraph::IsStandardConstant(HConstant* constant) {
|
||||
if (constant == GetConstantUndefined()) return true;
|
||||
if (constant == GetConstant0()) return true;
|
||||
if (constant == GetConstant1()) return true;
|
||||
if (constant == GetConstantMinus1()) return true;
|
||||
if (constant == GetConstantTrue()) return true;
|
||||
if (constant == GetConstantFalse()) return true;
|
||||
if (constant == GetConstantHole()) return true;
|
||||
if (constant == GetConstantNull()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
|
||||
: builder_(builder),
|
||||
position_(position),
|
||||
@ -4461,9 +4447,9 @@ void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) {
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) {
|
||||
void HOptimizedGraphBuilder::AddSoftDeoptimize() {
|
||||
isolate()->counters()->soft_deopts_requested()->Increment();
|
||||
if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return;
|
||||
if (FLAG_always_opt) return;
|
||||
if (current_block()->IsDeoptimizing()) return;
|
||||
Add<HSoftDeoptimize>();
|
||||
isolate()->counters()->soft_deopts_inserted()->Increment();
|
||||
@ -5416,20 +5402,9 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
|
||||
if (type == kUseCell) {
|
||||
Handle<GlobalObject> global(current_info()->global_object());
|
||||
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
|
||||
if (cell->type()->IsConstant()) {
|
||||
cell->AddDependentCompilationInfo(top_info());
|
||||
Handle<Object> constant_object = cell->type()->AsConstant();
|
||||
if (constant_object->IsConsString()) {
|
||||
constant_object =
|
||||
FlattenGetString(Handle<String>::cast(constant_object));
|
||||
}
|
||||
HConstant* constant = new(zone()) HConstant(constant_object);
|
||||
return ast_context()->ReturnInstruction(constant, expr->id());
|
||||
} else {
|
||||
HLoadGlobalCell* instr =
|
||||
new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
|
||||
return ast_context()->ReturnInstruction(instr, expr->id());
|
||||
}
|
||||
HLoadGlobalCell* instr =
|
||||
new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
|
||||
return ast_context()->ReturnInstruction(instr, expr->id());
|
||||
} else {
|
||||
HValue* context = environment()->LookupContext();
|
||||
HGlobalObject* global_object = new(zone()) HGlobalObject(context);
|
||||
@ -6336,21 +6311,8 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
|
||||
if (type == kUseCell) {
|
||||
Handle<GlobalObject> global(current_info()->global_object());
|
||||
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
|
||||
if (cell->type()->IsConstant()) {
|
||||
IfBuilder builder(this);
|
||||
HValue* constant = Add<HConstant>(cell->type()->AsConstant());
|
||||
if (cell->type()->AsConstant()->IsNumber()) {
|
||||
builder.IfCompare(value, constant, Token::EQ);
|
||||
} else {
|
||||
builder.If<HCompareObjectEqAndBranch>(value, constant);
|
||||
}
|
||||
builder.Then();
|
||||
builder.Else();
|
||||
AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT);
|
||||
builder.End();
|
||||
}
|
||||
HInstruction* instr =
|
||||
Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
|
||||
HInstruction* instr = Add<HStoreGlobalCell>(value, cell,
|
||||
lookup.GetPropertyDetails());
|
||||
instr->set_position(position);
|
||||
if (instr->HasObservableSideEffects()) {
|
||||
AddSimulate(ast_id, REMOVABLE_SIMULATE);
|
||||
|
@ -333,8 +333,6 @@ class HGraph: public ZoneObject {
|
||||
HConstant* GetConstantNull();
|
||||
HConstant* GetInvalidContext();
|
||||
|
||||
bool IsStandardConstant(HConstant* constant);
|
||||
|
||||
HBasicBlock* CreateBasicBlock();
|
||||
HArgumentsObject* GetArgumentsObject() const {
|
||||
return arguments_object_.get();
|
||||
@ -1494,12 +1492,7 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
|
||||
|
||||
bool inline_bailout() { return inline_bailout_; }
|
||||
|
||||
enum SoftDeoptimizeMode {
|
||||
MUST_EMIT_SOFT_DEOPT,
|
||||
CAN_OMIT_SOFT_DEOPT
|
||||
};
|
||||
|
||||
void AddSoftDeoptimize(SoftDeoptimizeMode mode = CAN_OMIT_SOFT_DEOPT);
|
||||
void AddSoftDeoptimize();
|
||||
|
||||
void Bailout(const char* reason);
|
||||
|
||||
|
@ -230,17 +230,6 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
|
||||
}
|
||||
|
||||
|
||||
void StoreGlobalStub::InitializeInterfaceDescriptor(
|
||||
Isolate* isolate,
|
||||
CodeStubInterfaceDescriptor* descriptor) {
|
||||
static Register registers[] = { edx, ecx, eax };
|
||||
descriptor->register_param_count_ = 3;
|
||||
descriptor->register_params_ = registers;
|
||||
descriptor->deoptimization_handler_ =
|
||||
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
|
||||
|
@ -115,7 +115,6 @@ class LCodeGen BASE_EMBEDDED {
|
||||
Immediate ToSmiImmediate(LOperand* op) const {
|
||||
return Immediate(Smi::FromInt(ToInteger32(LConstantOperand::cast(op))));
|
||||
}
|
||||
double ToDouble(LConstantOperand* op) const;
|
||||
|
||||
// Support for non-sse2 (x87) floating point stack handling.
|
||||
// These functions maintain the depth of the stack (either 0 or 1)
|
||||
@ -294,6 +293,7 @@ class LCodeGen BASE_EMBEDDED {
|
||||
XMMRegister ToDoubleRegister(int index) const;
|
||||
int ToInteger32(LConstantOperand* op) const;
|
||||
|
||||
double ToDouble(LConstantOperand* op) const;
|
||||
Operand BuildFastArrayOperand(LOperand* elements_pointer,
|
||||
LOperand* key,
|
||||
Representation key_representation,
|
||||
|
@ -313,31 +313,6 @@ void LGapResolver::EmitMove(int index) {
|
||||
} else {
|
||||
__ LoadObject(dst, cgen_->ToHandle(constant_source));
|
||||
}
|
||||
} else if (destination->IsDoubleRegister()) {
|
||||
double v = cgen_->ToDouble(constant_source);
|
||||
uint64_t int_val = BitCast<uint64_t, double>(v);
|
||||
int32_t lower = static_cast<int32_t>(int_val);
|
||||
int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
|
||||
if (CpuFeatures::IsSupported(SSE2)) {
|
||||
CpuFeatureScope scope(cgen_->masm(), SSE2);
|
||||
XMMRegister dst = cgen_->ToDoubleRegister(destination);
|
||||
if (int_val == 0) {
|
||||
__ xorps(dst, dst);
|
||||
} else {
|
||||
__ push(Immediate(upper));
|
||||
__ push(Immediate(lower));
|
||||
__ movdbl(dst, Operand(esp, 0));
|
||||
__ add(esp, Immediate(kDoubleSize));
|
||||
}
|
||||
} else {
|
||||
__ push(Immediate(upper));
|
||||
__ push(Immediate(lower));
|
||||
if (cgen_->X87StackNonEmpty()) {
|
||||
cgen_->PopX87();
|
||||
}
|
||||
cgen_->PushX87DoubleOperand(MemOperand(esp, 0));
|
||||
__ add(esp, Immediate(kDoubleSize));
|
||||
}
|
||||
} else {
|
||||
ASSERT(destination->IsStackSlot());
|
||||
Operand dst = cgen_->ToOperand(destination);
|
||||
|
24
src/ic.cc
24
src/ic.cc
@ -1668,7 +1668,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
||||
ASSERT(!lookup->IsHandler());
|
||||
|
||||
Handle<Code> code = ComputeStoreMonomorphic(
|
||||
lookup, strict_mode, receiver, name, value);
|
||||
lookup, strict_mode, receiver, name);
|
||||
if (code.is_null()) {
|
||||
Handle<Code> stub = strict_mode == kStrictMode
|
||||
? generic_stub_strict() : generic_stub();
|
||||
@ -1684,8 +1684,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
||||
Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
|
||||
StrictModeFlag strict_mode,
|
||||
Handle<JSObject> receiver,
|
||||
Handle<String> name,
|
||||
Handle<Object> value) {
|
||||
Handle<String> name) {
|
||||
Handle<JSObject> holder(lookup->holder());
|
||||
switch (lookup->type()) {
|
||||
case FIELD:
|
||||
@ -1700,7 +1699,7 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
|
||||
Handle<PropertyCell> cell(
|
||||
global->GetPropertyCell(lookup), isolate());
|
||||
return isolate()->stub_cache()->ComputeStoreGlobal(
|
||||
name, global, cell, value, strict_mode);
|
||||
name, global, cell, strict_mode);
|
||||
}
|
||||
ASSERT(holder.is_identical_to(receiver));
|
||||
return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
|
||||
@ -2094,8 +2093,7 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
||||
Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
|
||||
StrictModeFlag strict_mode,
|
||||
Handle<JSObject> receiver,
|
||||
Handle<String> name,
|
||||
Handle<Object> value) {
|
||||
Handle<String> name) {
|
||||
// If the property has a non-field type allowing map transitions
|
||||
// where there is extra room in the object, we leave the IC in its
|
||||
// current state.
|
||||
@ -2247,20 +2245,6 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) {
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 3);
|
||||
StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
|
||||
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
||||
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
|
||||
return ic.Store(state,
|
||||
Code::GetStrictMode(extra_ic_state),
|
||||
args.at<Object>(0),
|
||||
args.at<String>(1),
|
||||
args.at<Object>(2));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
|
||||
SealHandleScope shs(isolate);
|
||||
|
||||
|
7
src/ic.h
7
src/ic.h
@ -560,8 +560,7 @@ class StoreIC: public IC {
|
||||
virtual Handle<Code> ComputeStoreMonomorphic(LookupResult* lookup,
|
||||
StrictModeFlag strict_mode,
|
||||
Handle<JSObject> receiver,
|
||||
Handle<String> name,
|
||||
Handle<Object> value);
|
||||
Handle<String> name);
|
||||
|
||||
private:
|
||||
void set_target(Code* code) {
|
||||
@ -628,8 +627,7 @@ class KeyedStoreIC: public StoreIC {
|
||||
virtual Handle<Code> ComputeStoreMonomorphic(LookupResult* lookup,
|
||||
StrictModeFlag strict_mode,
|
||||
Handle<JSObject> receiver,
|
||||
Handle<String> name,
|
||||
Handle<Object> value);
|
||||
Handle<String> name);
|
||||
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
|
||||
|
||||
virtual Handle<Code> megamorphic_stub() {
|
||||
@ -840,7 +838,6 @@ void PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
|
||||
|
||||
DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure);
|
||||
DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure);
|
||||
DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure);
|
||||
DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
|
||||
DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
|
||||
|
||||
|
@ -3787,7 +3787,6 @@ int Code::major_key() {
|
||||
kind() == BINARY_OP_IC ||
|
||||
kind() == COMPARE_IC ||
|
||||
kind() == COMPARE_NIL_IC ||
|
||||
kind() == STORE_IC ||
|
||||
kind() == LOAD_IC ||
|
||||
kind() == KEYED_LOAD_IC ||
|
||||
kind() == TO_BOOLEAN_IC);
|
||||
|
@ -634,7 +634,7 @@ Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
|
||||
if (IsGlobalObject()) {
|
||||
PropertyCell* cell = PropertyCell::cast(
|
||||
property_dictionary()->ValueAt(result->GetDictionaryEntry()));
|
||||
cell->SetValueInferType(value);
|
||||
cell->set_value(value);
|
||||
} else {
|
||||
property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
|
||||
}
|
||||
@ -690,7 +690,7 @@ MaybeObject* JSObject::SetNormalizedProperty(Name* name,
|
||||
if (IsGlobalObject()) {
|
||||
PropertyCell* cell =
|
||||
PropertyCell::cast(property_dictionary()->ValueAt(entry));
|
||||
cell->SetValueInferType(value);
|
||||
cell->set_value(value);
|
||||
// Please note we have to update the property details.
|
||||
property_dictionary()->DetailsAtPut(entry, details);
|
||||
} else {
|
||||
@ -722,7 +722,7 @@ MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) {
|
||||
set_map(new_map);
|
||||
}
|
||||
PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
|
||||
cell->SetValueInferType(cell->GetHeap()->the_hole_value());
|
||||
cell->set_value(cell->GetHeap()->the_hole_value());
|
||||
dictionary->DetailsAtPut(entry, details.AsDeleted());
|
||||
} else {
|
||||
Object* deleted = dictionary->DeleteProperty(entry, mode);
|
||||
@ -1929,7 +1929,7 @@ MaybeObject* JSObject::AddSlowProperty(Name* name,
|
||||
int entry = dict->FindEntry(name);
|
||||
if (entry != NameDictionary::kNotFound) {
|
||||
store_value = dict->ValueAt(entry);
|
||||
PropertyCell::cast(store_value)->SetValueInferType(value);
|
||||
PropertyCell::cast(store_value)->set_value(value);
|
||||
// Assign an enumeration index to the property and update
|
||||
// SetNextEnumerationIndex.
|
||||
int index = dict->NextEnumerationIndex();
|
||||
@ -1943,7 +1943,7 @@ MaybeObject* JSObject::AddSlowProperty(Name* name,
|
||||
heap->AllocatePropertyCell(value);
|
||||
if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
|
||||
}
|
||||
PropertyCell::cast(store_value)->SetValueInferType(value);
|
||||
PropertyCell::cast(store_value)->set_value(value);
|
||||
}
|
||||
PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
|
||||
Object* result;
|
||||
@ -15806,38 +15806,6 @@ void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
|
||||
}
|
||||
|
||||
|
||||
Type* PropertyCell::UpdateType(Object* value) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
Handle<Object> value_handle(value, isolate);
|
||||
Handle<Type> old_type(type(), isolate);
|
||||
Handle<Type> new_type((value->IsSmi() || value->IsUndefined())
|
||||
? Type::Constant(value_handle, isolate)
|
||||
: Type::Any(), isolate);
|
||||
|
||||
if (new_type->Is(old_type)) {
|
||||
return *old_type;
|
||||
}
|
||||
|
||||
dependent_code()->DeoptimizeDependentCodeGroup(
|
||||
isolate, DependentCode::kPropertyCellChangedGroup);
|
||||
|
||||
if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
|
||||
return *new_type;
|
||||
}
|
||||
|
||||
return Type::Any();
|
||||
}
|
||||
|
||||
|
||||
void PropertyCell::SetValueInferType(Object* value,
|
||||
WriteBarrierMode ignored) {
|
||||
set_value(value, ignored);
|
||||
if (!Type::Any()->Is(type())) {
|
||||
set_type(UpdateType(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) {
|
||||
Handle<DependentCode> dep(dependent_code());
|
||||
Handle<DependentCode> codes =
|
||||
|
@ -8585,13 +8585,6 @@ class PropertyCell: public Cell {
|
||||
// property.
|
||||
DECL_ACCESSORS(dependent_code, DependentCode)
|
||||
|
||||
// Sets the value of the cell and updates the type field to be the union
|
||||
// of the cell's current type and the value's type. If the change causes
|
||||
// a change of the type of the cell's contents, code dependent on the cell
|
||||
// will be deoptimized.
|
||||
void SetValueInferType(Object* value,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
// Casting.
|
||||
static inline PropertyCell* cast(Object* obj);
|
||||
|
||||
@ -8619,8 +8612,6 @@ class PropertyCell: public Cell {
|
||||
|
||||
void AddDependentCode(Handle<Code> code);
|
||||
|
||||
Type* UpdateType(Object* value);
|
||||
|
||||
private:
|
||||
DECL_ACCESSORS(type_raw, Object)
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
|
||||
|
@ -2110,7 +2110,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
|
||||
} else if (lookup.IsNormal()) {
|
||||
if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
|
||||
!lookup.IsReadOnly()) {
|
||||
HandleScope scope(isolate);
|
||||
global->SetNormalizedProperty(&lookup, *value);
|
||||
}
|
||||
} else {
|
||||
|
@ -498,30 +498,15 @@ Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
|
||||
Handle<Code> StubCache::ComputeStoreGlobal(Handle<Name> name,
|
||||
Handle<GlobalObject> receiver,
|
||||
Handle<PropertyCell> cell,
|
||||
Handle<Object> value,
|
||||
StrictModeFlag strict_mode) {
|
||||
Isolate* isolate = cell->GetIsolate();
|
||||
Handle<Type> union_type(cell->UpdateType(*value), isolate);
|
||||
bool is_constant = union_type->IsConstant();
|
||||
StoreGlobalStub stub(strict_mode, is_constant);
|
||||
|
||||
Handle<Code> code = FindIC(
|
||||
Handle<Code> stub = FindIC(
|
||||
name, Handle<JSObject>::cast(receiver),
|
||||
Code::STORE_IC, Code::NORMAL, stub.GetExtraICState());
|
||||
if (!code.is_null()) return code;
|
||||
Code::STORE_IC, Code::NORMAL, strict_mode);
|
||||
if (!stub.is_null()) return stub;
|
||||
|
||||
if (is_constant) return stub.GetCode(isolate_);
|
||||
|
||||
// Replace the placeholder cell and global object map with the actual global
|
||||
// cell and receiver map.
|
||||
Handle<Map> cell_map(isolate_->heap()->global_property_cell_map());
|
||||
Handle<Map> meta_map(isolate_->heap()->meta_map());
|
||||
Handle<Object> receiver_map(receiver->map(), isolate_);
|
||||
code = stub.GetCodeCopyFromTemplate(isolate_);
|
||||
code->ReplaceNthObject(1, *meta_map, *receiver_map);
|
||||
code->ReplaceNthObject(1, *cell_map, *cell);
|
||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||
Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
|
||||
JSObject::UpdateMapCodeCache(receiver, name, code);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -936,8 +921,12 @@ Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
|
||||
if (!cached_ic.is_null()) return cached_ic;
|
||||
}
|
||||
|
||||
Handle<Code> ic = stub.GetCodeCopyFromTemplate(isolate_);
|
||||
ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map);
|
||||
Handle<Code> ic = stub.GetCode(isolate_);
|
||||
|
||||
// For monomorphic maps, use the code as a template, copying and replacing
|
||||
// the monomorphic map that checks the object's type.
|
||||
ic = isolate_->factory()->CopyCode(ic);
|
||||
ic->ReplaceFirstMap(*receiver_map);
|
||||
|
||||
if (!receiver_map->is_shared()) {
|
||||
Map::UpdateCodeCache(receiver_map, name, ic);
|
||||
|
@ -184,7 +184,6 @@ class StubCache {
|
||||
Handle<Code> ComputeStoreGlobal(Handle<Name> name,
|
||||
Handle<GlobalObject> object,
|
||||
Handle<PropertyCell> cell,
|
||||
Handle<Object> value,
|
||||
StrictModeFlag strict_mode);
|
||||
|
||||
Handle<Code> ComputeStoreCallback(Handle<Name> name,
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
@ -226,17 +226,6 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
|
||||
}
|
||||
|
||||
|
||||
void StoreGlobalStub::InitializeInterfaceDescriptor(
|
||||
Isolate* isolate,
|
||||
CodeStubInterfaceDescriptor* descriptor) {
|
||||
static Register registers[] = { rdx, rcx, rax };
|
||||
descriptor->register_param_count_ = 3;
|
||||
descriptor->register_params_ = registers;
|
||||
descriptor->deoptimization_handler_ =
|
||||
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
|
||||
|
@ -202,20 +202,6 @@ void LGapResolver::EmitMove(int index) {
|
||||
} else {
|
||||
__ LoadObject(dst, cgen_->ToHandle(constant_source));
|
||||
}
|
||||
} else if (destination->IsDoubleRegister()) {
|
||||
double v = cgen_->ToDouble(constant_source);
|
||||
uint64_t int_val = BitCast<uint64_t, double>(v);
|
||||
int32_t lower = static_cast<int32_t>(int_val);
|
||||
int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
|
||||
XMMRegister dst = cgen_->ToDoubleRegister(destination);
|
||||
if (int_val == 0) {
|
||||
__ xorps(dst, dst);
|
||||
} else {
|
||||
__ push(Immediate(upper));
|
||||
__ push(Immediate(lower));
|
||||
__ movsd(dst, Operand(rsp, 0));
|
||||
__ addq(rsp, Immediate(kDoubleSize));
|
||||
}
|
||||
} else {
|
||||
ASSERT(destination->IsStackSlot());
|
||||
Operand dst = cgen_->ToOperand(destination);
|
||||
|
@ -30,7 +30,7 @@
|
||||
function f() {
|
||||
do {
|
||||
do {
|
||||
for (var i = 0; i < 10000000; i++) {
|
||||
for (i = 0; i < 10000000; i++) {
|
||||
// This should run long enough to trigger OSR.
|
||||
}
|
||||
} while (false);
|
||||
@ -46,7 +46,7 @@ function g() {
|
||||
|
||||
do {
|
||||
do {
|
||||
for (var i = 0; i < 1; i++) { }
|
||||
for (i = 0; i < 1; i++) { }
|
||||
} while (false);
|
||||
} while (false);
|
||||
|
||||
@ -58,7 +58,7 @@ function g() {
|
||||
do {
|
||||
do {
|
||||
do {
|
||||
for (var i = 0; i < 10000000; i++) { }
|
||||
for (i = 0; i < 10000000; i++) { }
|
||||
} while (false);
|
||||
} while (false);
|
||||
} while (false);
|
||||
|
Loading…
Reference in New Issue
Block a user