Revision: 13475
Author: [email protected]
Date: Wed Jan 23 05:52:00 2013
Log: Avoid handle dereference during graph optimization.
With parallel recompilation enabled, objects made accessible by handles may
have changed between graph construction and graph optimization. Therefore
we must not assume that information on those objects remain the same between
those two phases. To police this, we forbid handle dereferencing during
graph optimization.
Exceptions to this rule are:
- Dereferencing the handle to obtain the raw location of the object. This
is safe since parallel recompilation acquires RelocationLock
- Some places that dereference the handle for a type check. These are
checked
to be safe on a case-by-case basis.
[email protected]
BUG=
Review URL: https://chromiumcodereview.appspot.com/12049012
http://code.google.com/p/v8/source/detail?r=13475
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/compiler.cc
/branches/bleeding_edge/src/compiler.h
/branches/bleeding_edge/src/handles-inl.h
/branches/bleeding_edge/src/handles.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/hydrogen.h
/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/isolate.cc
/branches/bleeding_edge/src/isolate.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/src/arm/lithium-arm.cc Thu Jan 17 06:07:47 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Jan 23 05:52:00 2013
@@ -2098,9 +2098,7 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- ElementsKind from_kind = instr->original_map()->elements_kind();
- ElementsKind to_kind = instr->transitioned_map()->elements_kind();
- if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+ if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
@@ -2355,8 +2353,8 @@
instr->arguments_count(),
instr->function(),
undefined,
- instr->call_kind(),
- instr->inlining_kind());
+ instr->inlining_kind(),
+
instr->undefined_receiver());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Mon Jan 21 07:49:00 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Jan 23 05:52:00 2013
@@ -2054,6 +2054,8 @@
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
+ ElementsKind from_kind() { return hydrogen()->from_kind(); }
+ ElementsKind to_kind() { return hydrogen()->to_kind(); }
};
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Jan 21
07:49:00 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jan 23
05:52:00 2013
@@ -818,8 +818,7 @@
ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on
ARM.
- if (FLAG_deopt_every_n_times == 1 &&
- info_->shared_info()->opt_count() == id) {
+ if (FLAG_deopt_every_n_times == 1 && info_->opt_count() == id) {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
return;
}
@@ -4508,8 +4507,8 @@
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
- ElementsKind from_kind = from_map->elements_kind();
- ElementsKind to_kind = to_map->elements_kind();
+ ElementsKind from_kind = instr->from_kind();
+ ElementsKind to_kind = instr->to_kind();
Label not_applicable;
__ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
=======================================
--- /branches/bleeding_edge/src/compiler.cc Tue Jan 15 02:16:52 2013
+++ /branches/bleeding_edge/src/compiler.cc Wed Jan 23 05:52:00 2013
@@ -101,6 +101,7 @@
deferred_handles_ = NULL;
code_stub_ = NULL;
prologue_offset_ = kPrologueOffsetNotSet;
+ opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
if (mode == STUB) {
mode_ = STUB;
return;
@@ -285,7 +286,7 @@
// the optimizing compiler.
const int kMaxOptCount =
FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000;
- if (info()->shared_info()->opt_count() > kMaxOptCount) {
+ if (info()->opt_count() > kMaxOptCount) {
info()->set_bailout_reason("optimized too many times");
return AbortOptimization();
}
@@ -394,6 +395,7 @@
OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() {
AssertNoAllocation no_gc;
NoHandleAllocation no_handles;
+ NoHandleDereference no_deref;
ASSERT(last_status() == SUCCEEDED);
Timer t(this, &time_taken_to_optimize_);
=======================================
--- /branches/bleeding_edge/src/compiler.h Tue Dec 18 08:25:45 2012
+++ /branches/bleeding_edge/src/compiler.h Wed Jan 23 05:52:00 2013
@@ -79,6 +79,7 @@
ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
Handle<Context> context() const { return context_; }
BailoutId osr_ast_id() const { return osr_ast_id_; }
+ int opt_count() const { return opt_count_; }
int num_parameters() const;
int num_heap_slots() const;
Code::Flags flags() const;
@@ -326,6 +327,10 @@
int prologue_offset_;
+ // A copy of shared_info()->opt_count() to avoid handle deref
+ // during graph optimization.
+ int opt_count_;
+
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};
=======================================
--- /branches/bleeding_edge/src/handles-inl.h Thu Jul 19 11:58:23 2012
+++ /branches/bleeding_edge/src/handles-inl.h Wed Jan 23 05:52:00 2013
@@ -63,9 +63,18 @@
inline T* Handle<T>::operator*() const {
ASSERT(location_ != NULL);
ASSERT(reinterpret_cast<Address>(*location_) != kHandleZapValue);
+ SLOW_ASSERT(ISOLATE->allow_handle_deref());
return *BitCast<T**>(location_);
}
+template <typename T>
+inline T** Handle<T>::location() const {
+ ASSERT(location_ == NULL ||
+ reinterpret_cast<Address>(*location_) != kZapValue);
+ SLOW_ASSERT(ISOLATE->allow_handle_deref());
+ return location_;
+}
+
HandleScope::HandleScope() {
Isolate* isolate = Isolate::Current();
@@ -175,6 +184,38 @@
data->level = level_;
}
}
+
+
+NoHandleDereference::NoHandleDereference() {
+ // The guard is set on a per-isolate basis, so it affects all threads.
+ // That's why we can only use it when running without parallel
recompilation.
+ if (FLAG_parallel_recompilation) return;
+ Isolate* isolate = Isolate::Current();
+ old_state_ = isolate->allow_handle_deref();
+ isolate->set_allow_handle_deref(false);
+}
+
+
+NoHandleDereference::~NoHandleDereference() {
+ if (FLAG_parallel_recompilation) return;
+ Isolate::Current()->set_allow_handle_deref(old_state_);
+}
+
+
+AllowHandleDereference::AllowHandleDereference() {
+ // The guard is set on a per-isolate basis, so it affects all threads.
+ // That's why we can only use it when running without parallel
recompilation.
+ if (FLAG_parallel_recompilation) return;
+ Isolate* isolate = Isolate::Current();
+ old_state_ = isolate->allow_handle_deref();
+ isolate->set_allow_handle_deref(true);
+}
+
+
+AllowHandleDereference::~AllowHandleDereference() {
+ if (FLAG_parallel_recompilation) return;
+ Isolate::Current()->set_allow_handle_deref(old_state_);
+}
#endif
=======================================
--- /branches/bleeding_edge/src/handles.h Thu Jan 3 04:59:54 2013
+++ /branches/bleeding_edge/src/handles.h Wed Jan 23 05:52:00 2013
@@ -58,25 +58,21 @@
a = b; // Fake assignment to enforce type checks.
USE(a);
#endif
- location_ = reinterpret_cast<T**>(handle.location());
+ location_ = reinterpret_cast<T**>(handle.location_);
}
INLINE(T* operator ->() const) { return operator*(); }
// Check if this handle refers to the exact same object as the other
handle.
bool is_identical_to(const Handle<T> other) const {
- return operator*() == *other;
+ return *location_ == *other.location_;
}
// Provides the C++ dereference operator.
INLINE(T* operator*() const);
// Returns the address to where the raw pointer is stored.
- T** location() const {
- ASSERT(location_ == NULL ||
- reinterpret_cast<Address>(*location_) != kZapValue);
- return location_;
- }
+ INLINE(T** location() const);
template <class S> static Handle<T> cast(Handle<S> that) {
T::cast(*that);
@@ -92,6 +88,9 @@
private:
T** location_;
+
+ // Handles of different classes are allowed to access each other's
location_.
+ template<class S> friend class Handle;
};
@@ -339,6 +338,34 @@
#endif
};
+
+class NoHandleDereference BASE_EMBEDDED {
+ public:
+#ifndef DEBUG
+ NoHandleDereference() {}
+ ~NoHandleDereference() {}
+#else
+ inline NoHandleDereference();
+ inline ~NoHandleDereference();
+ private:
+ bool old_state_;
+#endif
+};
+
+
+class AllowHandleDereference BASE_EMBEDDED {
+ public:
+#ifndef DEBUG
+ AllowHandleDereference() {}
+ ~AllowHandleDereference() {}
+#else
+ inline AllowHandleDereference();
+ inline ~AllowHandleDereference();
+ private:
+ bool old_state_;
+#endif
+};
+
} } // namespace v8::internal
#endif // V8_HANDLES_H_
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Jan 21
07:49:00 2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Jan 23
05:52:00 2013
@@ -342,6 +342,10 @@
HType HType::TypeFromValue(Handle<Object> value) {
+ // Handle dereferencing is safe here: an object's type as checked below
+ // never changes.
+ AllowHandleDereference allow_handle_deref;
+
HType result = HType::Tagged();
if (value->IsSmi()) {
result = HType::Smi();
@@ -1119,10 +1123,11 @@
value()->type().IsString()) {
return NULL;
}
- if (check_ == IS_SYMBOL &&
- value()->IsConstant() &&
- HConstant::cast(value())->handle()->IsSymbol()) {
- return NULL;
+
+ if (check_ == IS_SYMBOL && value()->IsConstant()) {
+ // Dereferencing is safe here: a symbol cannot become a non-symbol.
+ AllowHandleDereference allow_handle_deref;
+ if (HConstant::cast(value())->handle()->IsSymbol()) return NULL;
}
return this;
}
@@ -1555,6 +1560,8 @@
: handle_(handle),
has_int32_value_(false),
has_double_value_(false) {
+ // Dereferencing here is safe: the value of a number object does not
change.
+ AllowHandleDereference allow_handle_deref;
SetFlag(kUseGVN);
if (handle_->IsNumber()) {
double n = handle_->Number();
@@ -1633,12 +1640,14 @@
double v = DoubleValue();
return v != 0 && !isnan(v);
}
- Handle<Object> literal = handle();
- if (literal->IsTrue()) return true;
- if (literal->IsFalse()) return false;
- if (literal->IsUndefined()) return false;
- if (literal->IsNull()) return false;
- if (literal->IsString() && String::cast(*literal)->length() == 0) {
+ // Dereferencing is safe: singletons do not change and strings are
+ // immutable.
+ AllowHandleDereference allow_handle_deref;
+ if (handle_->IsTrue()) return true;
+ if (handle_->IsFalse()) return false;
+ if (handle_->IsUndefined()) return false;
+ if (handle_->IsNull()) return false;
+ if (handle_->IsString() && String::cast(*handle_)->length() == 0) {
return false;
}
return true;
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jan 21 07:49:00
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Jan 23 05:52:00
2013
@@ -1496,18 +1496,18 @@
HEnterInlined(Handle<JSFunction> closure,
int arguments_count,
FunctionLiteral* function,
- CallKind call_kind,
InliningKind inlining_kind,
Variable* arguments_var,
- ZoneList<HValue*>* arguments_values)
+ ZoneList<HValue*>* arguments_values,
+ bool undefined_receiver)
: closure_(closure),
arguments_count_(arguments_count),
arguments_pushed_(false),
function_(function),
- call_kind_(call_kind),
inlining_kind_(inlining_kind),
arguments_var_(arguments_var),
- arguments_values_(arguments_values) {
+ arguments_values_(arguments_values),
+ undefined_receiver_(undefined_receiver) {
}
virtual void PrintDataTo(StringStream* stream);
@@ -1517,8 +1517,8 @@
bool arguments_pushed() const { return arguments_pushed_; }
void set_arguments_pushed() { arguments_pushed_ = true; }
FunctionLiteral* function() const { return function_; }
- CallKind call_kind() const { return call_kind_; }
InliningKind inlining_kind() const { return inlining_kind_; }
+ bool undefined_receiver() const { return undefined_receiver_; }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -1534,10 +1534,10 @@
int arguments_count_;
bool arguments_pushed_;
FunctionLiteral* function_;
- CallKind call_kind_;
InliningKind inlining_kind_;
Variable* arguments_var_;
ZoneList<HValue*>* arguments_values_;
+ bool undefined_receiver_;
};
@@ -2322,6 +2322,7 @@
: HUnaryOperation(value), target_(function) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
+ target_in_new_space_ =
Isolate::Current()->heap()->InNewSpace(*function);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -2335,6 +2336,7 @@
#endif
Handle<JSFunction> target() const { return target_; }
+ bool target_in_new_space() const { return target_in_new_space_; }
DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
@@ -2346,6 +2348,7 @@
private:
Handle<JSFunction> target_;
+ bool target_in_new_space_;
};
@@ -2475,6 +2478,8 @@
virtual intptr_t Hashcode() {
ASSERT_ALLOCATION_DISABLED;
+ // Dereferencing to use the object's raw address for hashing is safe.
+ AllowHandleDereference allow_handle_deref;
intptr_t hash = 0;
for (int i = 0; i < prototypes_.length(); i++) {
hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]);
@@ -2692,15 +2697,16 @@
Heap* heap = HEAP;
// We should have handled minus_zero_value and nan_value in the
// has_double_value_ clause above.
+ // Dereferencing is safe to compare against singletons.
+ AllowHandleDereference allow_handle_deref;
ASSERT(*handle_ != heap->minus_zero_value());
ASSERT(*handle_ != heap->nan_value());
- if (*handle_ == heap->undefined_value()) return true;
- if (*handle_ == heap->null_value()) return true;
- if (*handle_ == heap->true_value()) return true;
- if (*handle_ == heap->false_value()) return true;
- if (*handle_ == heap->the_hole_value()) return true;
- if (*handle_ == heap->empty_string()) return true;
- return false;
+ return *handle_ == heap->undefined_value() ||
+ *handle_ == heap->null_value() ||
+ *handle_ == heap->true_value() ||
+ *handle_ == heap->false_value() ||
+ *handle_ == heap->the_hole_value() ||
+ *handle_ == heap->empty_string();
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -2752,6 +2758,8 @@
hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
} else {
ASSERT(!handle_.is_null());
+ // Dereferencing to use the object's raw address for hashing is safe.
+ AllowHandleDereference allow_handle_deref;
hash = reinterpret_cast<intptr_t>(*handle_);
}
@@ -2779,7 +2787,7 @@
} else {
ASSERT(!handle_.is_null());
return !other_constant->handle_.is_null() &&
- *handle_ == *other_constant->handle_;
+ handle_.is_identical_to(other_constant->handle_);
}
}
@@ -4013,13 +4021,15 @@
SetGVNFlag(kDependsOnGlobalVars);
}
- Handle<JSGlobalPropertyCell> cell() const { return cell_; }
+ Handle<JSGlobalPropertyCell> cell() const { return cell_; }
bool RequiresHoleCheck() const;
virtual void PrintDataTo(StringStream* stream);
virtual intptr_t Hashcode() {
ASSERT_ALLOCATION_DISABLED;
+ // Dereferencing to use the object's raw address for hashing is safe.
+ AllowHandleDereference allow_handle_deref;
return reinterpret_cast<intptr_t>(*cell_);
}
@@ -4812,7 +4822,9 @@
Handle<Map> original_map,
Handle<Map> transitioned_map)
: original_map_(original_map),
- transitioned_map_(transitioned_map) {
+ transitioned_map_(transitioned_map),
+ from_kind_(original_map->elements_kind()),
+ to_kind_(transitioned_map->elements_kind()) {
SetOperandAt(0, object);
SetFlag(kUseGVN);
SetGVNFlag(kChangesElementsKind);
@@ -4834,6 +4846,8 @@
HValue* object() { return OperandAt(0); }
Handle<Map> original_map() { return original_map_; }
Handle<Map> transitioned_map() { return transitioned_map_; }
+ ElementsKind from_kind() { return from_kind_; }
+ ElementsKind to_kind() { return to_kind_; }
virtual void PrintDataTo(StringStream* stream);
@@ -4849,6 +4863,8 @@
private:
Handle<Map> original_map_;
Handle<Map> transitioned_map_;
+ ElementsKind from_kind_;
+ ElementsKind to_kind_;
};
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Tue Jan 22 05:55:22 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Jan 23 05:52:00 2013
@@ -497,6 +497,8 @@
void HGraph::Verify(bool do_full_verify) const {
+ // Allow dereferencing for debug mode verification.
+ AllowHandleDereference allow_handle_deref;
for (int i = 0; i < blocks_.length(); i++) {
HBasicBlock* block = blocks_.at(i);
@@ -2242,7 +2244,7 @@
bool HGlobalValueNumberer::AllowCodeMotion() {
- return info()->shared_info()->opt_count() + 1 < FLAG_max_opt_count;
+ return info()->opt_count() + 1 < FLAG_max_opt_count;
}
@@ -7221,13 +7223,15 @@
this, &target_info, &target_oracle, inlining_kind);
HConstant* undefined = graph()->GetConstantUndefined();
+ bool undefined_receiver = HEnvironment::UseUndefinedReceiver(
+ target, function, call_kind, inlining_kind);
HEnvironment* inner_env =
environment()->CopyForInlining(target,
arguments_count,
function,
undefined,
- call_kind,
- function_state()->inlining_kind());
+ function_state()->inlining_kind(),
+ undefined_receiver);
#ifdef V8_TARGET_ARCH_IA32
// IA32 only, overwrite the caller's context in the deoptimization
// environment with the correct one.
@@ -7261,10 +7265,10 @@
new(zone()) HEnterInlined(target,
arguments_count,
function,
- call_kind,
function_state()->inlining_kind(),
function->scope()->arguments(),
- arguments_values);
+ arguments_values,
+ undefined_receiver);
function_state()->set_entry(enter_inlined);
AddInstruction(enter_inlined);
@@ -9886,8 +9890,8 @@
int arguments,
FunctionLiteral* function,
HConstant* undefined,
- CallKind call_kind,
- InliningKind inlining_kind) const {
+ InliningKind inlining_kind,
+ bool undefined_receiver) const {
ASSERT(frame_type() == JS_FUNCTION);
// Outer environment is a copy of this one without the arguments.
@@ -9928,8 +9932,7 @@
// If the function we are inlining is a strict mode function or a
// builtin function, pass undefined as the receiver for function
// calls (instead of the global receiver).
- if ((target->shared()->native() || !function->is_classic_mode()) &&
- call_kind == CALL_AS_FUNCTION && inlining_kind !=
CONSTRUCT_CALL_RETURN) {
+ if (undefined_receiver) {
inner->SetValueAt(0, undefined);
}
inner->SetValueAt(arity + 1, LookupContext());
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Thu Jan 17 08:09:08 2013
+++ /branches/bleeding_edge/src/hydrogen.h Wed Jan 23 05:52:00 2013
@@ -552,8 +552,16 @@
int arguments,
FunctionLiteral* function,
HConstant* undefined,
- CallKind call_kind,
- InliningKind inlining_kind) const;
+ InliningKind inlining_kind,
+ bool undefined_receiver) const;
+
+ static bool UseUndefinedReceiver(Handle<JSFunction> closure,
+ FunctionLiteral* function,
+ CallKind call_kind,
+ InliningKind inlining_kind) {
+ return (closure->shared()->native() || !function->is_classic_mode()) &&
+ call_kind == CALL_AS_FUNCTION && inlining_kind !=
CONSTRUCT_CALL_RETURN;
+ }
HEnvironment* DiscardInlined(bool drop_extra) {
HEnvironment* outer = outer_;
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Jan 21
07:49:00 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jan 23
05:52:00 2013
@@ -4309,8 +4309,8 @@
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
- ElementsKind from_kind = from_map->elements_kind();
- ElementsKind to_kind = to_map->elements_kind();
+ ElementsKind from_kind = instr->from_kind();
+ ElementsKind to_kind = instr->to_kind();
Label not_applicable;
bool is_simple_map_transition =
@@ -5072,7 +5072,7 @@
void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
Handle<JSFunction> target = instr->hydrogen()->target();
- if (isolate()->heap()->InNewSpace(*target)) {
+ if (instr->hydrogen()->target_in_new_space()) {
Register reg = ToRegister(instr->value());
Handle<JSGlobalPropertyCell> cell =
isolate()->factory()->NewJSGlobalPropertyCell(target);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Jan 17 06:07:47
2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Jan 23 05:52:00
2013
@@ -1863,9 +1863,8 @@
// want the value in a register. If the target 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 =
Isolate::Current()->heap()->InNewSpace(*instr->target())
- ? UseRegisterAtStart(instr->value())
- : UseAtStart(instr->value());
+ LOperand* value = instr->target_in_new_space()
+ ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value());
return AssignEnvironment(new(zone()) LCheckFunction(value));
}
@@ -2160,9 +2159,7 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- ElementsKind from_kind = instr->original_map()->elements_kind();
- ElementsKind to_kind = instr->transitioned_map()->elements_kind();
- if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+ if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LOperand* temp_reg = TempRegister();
@@ -2451,8 +2448,8 @@
instr->arguments_count(),
instr->function(),
undefined,
- instr->call_kind(),
- instr->inlining_kind());
+ instr->inlining_kind(),
+
instr->undefined_receiver());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Mon Jan 21 07:49:00 2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Jan 23 05:52:00 2013
@@ -2114,6 +2114,8 @@
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
+ ElementsKind from_kind() { return hydrogen()->from_kind(); }
+ ElementsKind to_kind() { return hydrogen()->to_kind(); }
};
=======================================
--- /branches/bleeding_edge/src/isolate.cc Fri Jan 18 05:05:03 2013
+++ /branches/bleeding_edge/src/isolate.cc Wed Jan 23 05:52:00 2013
@@ -1677,6 +1677,8 @@
memset(&js_spill_information_, 0, sizeof(js_spill_information_));
memset(code_kind_statistics_, 0,
sizeof(code_kind_statistics_[0]) * Code::NUMBER_OF_KINDS);
+
+ allow_handle_deref_ = true;
#endif
#ifdef ENABLE_DEBUGGER_SUPPORT
=======================================
--- /branches/bleeding_edge/src/isolate.h Thu Jan 17 23:20:17 2013
+++ /branches/bleeding_edge/src/isolate.h Wed Jan 23 05:52:00 2013
@@ -969,6 +969,9 @@
}
int* code_kind_statistics() { return code_kind_statistics_; }
+
+ bool allow_handle_deref() { return allow_handle_deref_; }
+ void set_allow_handle_deref(bool allow) { allow_handle_deref_ = allow; }
#endif
#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
@@ -1266,6 +1269,8 @@
HistogramInfo heap_histograms_[LAST_TYPE + 1];
JSObject::SpillInformation js_spill_information_;
int code_kind_statistics_[Code::NUMBER_OF_KINDS];
+
+ bool allow_handle_deref_;
#endif
#ifdef ENABLE_DEBUGGER_SUPPORT
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Jan 21
07:49:00 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jan 23
05:52:00 2013
@@ -4132,8 +4132,8 @@
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
- ElementsKind from_kind = from_map->elements_kind();
- ElementsKind to_kind = to_map->elements_kind();
+ ElementsKind from_kind = instr->from_kind();
+ ElementsKind to_kind = instr->to_kind();
Label not_applicable;
__ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Thu Jan 17 06:07:47 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Jan 23 05:52:00 2013
@@ -2039,9 +2039,7 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- ElementsKind from_kind = instr->original_map()->elements_kind();
- ElementsKind to_kind = instr->transitioned_map()->elements_kind();
- if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+ if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LOperand* temp_reg = TempRegister();
@@ -2299,8 +2297,8 @@
instr->arguments_count(),
instr->function(),
undefined,
- instr->call_kind(),
- instr->inlining_kind());
+ instr->inlining_kind(),
+
instr->undefined_receiver());
if (instr->arguments_var() != NULL) {
inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Mon Jan 21 07:49:00 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Jan 23 05:52:00 2013
@@ -1993,6 +1993,8 @@
Handle<Map> original_map() { return hydrogen()->original_map(); }
Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
+ ElementsKind from_kind() { return hydrogen()->from_kind(); }
+ ElementsKind to_kind() { return hydrogen()->to_kind(); }
};
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev