Update V8 to r5675 as required by WebKit r70209
Change-Id: Ib10adb470d41ca8c109ead5fc893b880e18d489f
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 9c8573c..f2ac7f7 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -179,20 +179,11 @@
// Adjust for function-level loop nesting.
ASSERT_EQ(0, loop_nesting_);
- loop_nesting_ = info->loop_nesting();
+ loop_nesting_ = info->is_in_loop() ? 1 : 0;
JumpTarget::set_compiling_deferred_code(false);
-#ifdef DEBUG
- if (strlen(FLAG_stop_at) > 0 &&
- info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
- frame_->SpillAll();
- __ int3();
- }
-#endif
-
- // New scope to get automatic timing calculation.
- { HistogramTimerScope codegen_timer(&Counters::code_generation);
+ {
CodeGenState state(this);
// Entry:
@@ -203,6 +194,14 @@
// esi: callee's context
allocator_->Initialize();
+#ifdef DEBUG
+ if (strlen(FLAG_stop_at) > 0 &&
+ info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+ frame_->SpillAll();
+ __ int3();
+ }
+#endif
+
frame_->Enter();
// Allocate space for locals and initialize them.
@@ -358,7 +357,7 @@
}
// Adjust for function-level loop nesting.
- ASSERT_EQ(loop_nesting_, info->loop_nesting());
+ ASSERT_EQ(loop_nesting_, info->is_in_loop() ? 1 : 0);
loop_nesting_ = 0;
// Code generation state must be reset.
@@ -369,7 +368,6 @@
// Process any deferred code using the register allocator.
if (!HasStackOverflow()) {
- HistogramTimerScope deferred_timer(&Counters::deferred_code_generation);
JumpTarget::set_compiling_deferred_code(true);
ProcessDeferred();
JumpTarget::set_compiling_deferred_code(false);
@@ -4925,9 +4923,12 @@
ASSERT(!in_safe_int32_mode());
// Build the function info and instantiate it.
Handle<SharedFunctionInfo> function_info =
- Compiler::BuildFunctionInfo(node, script(), this);
+ Compiler::BuildFunctionInfo(node, script());
// Check for stack-overflow exception.
- if (HasStackOverflow()) return;
+ if (function_info.is_null()) {
+ SetStackOverflow();
+ return;
+ }
Result result = InstantiateFunction(function_info);
frame()->Push(&result);
}
@@ -9149,7 +9150,8 @@
: dst_(dst),
receiver_(receiver),
name_(name),
- is_contextual_(is_contextual) {
+ is_contextual_(is_contextual),
+ is_dont_delete_(false) {
set_comment(is_contextual
? "[ DeferredReferenceGetNamedValue (contextual)"
: "[ DeferredReferenceGetNamedValue");
@@ -9159,12 +9161,18 @@
Label* patch_site() { return &patch_site_; }
+ void set_is_dont_delete(bool value) {
+ ASSERT(is_contextual_);
+ is_dont_delete_ = value;
+ }
+
private:
Label patch_site_;
Register dst_;
Register receiver_;
Handle<String> name_;
bool is_contextual_;
+ bool is_dont_delete_;
};
@@ -9181,8 +9189,8 @@
// The call must be followed by:
// - a test eax instruction to indicate that the inobject property
// case was inlined.
- // - a mov ecx instruction to indicate that the contextual property
- // load was inlined.
+ // - a mov ecx or mov edx instruction to indicate that the
+ // contextual property load was inlined.
//
// Store the delta to the map check instruction here in the test
// instruction. Use masm_-> instead of the __ macro since the
@@ -9191,8 +9199,11 @@
// Here we use masm_-> instead of the __ macro because this is the
// instruction that gets patched and coverage code gets in the way.
if (is_contextual_) {
- masm_->mov(ecx, -delta_to_patch_site);
+ masm_->mov(is_dont_delete_ ? edx : ecx, -delta_to_patch_site);
__ IncrementCounter(&Counters::named_load_global_inline_miss, 1);
+ if (is_dont_delete_) {
+ __ IncrementCounter(&Counters::dont_delete_hint_miss, 1);
+ }
} else {
masm_->test(eax, Immediate(-delta_to_patch_site));
__ IncrementCounter(&Counters::named_load_inline_miss, 1);
@@ -9436,9 +9447,34 @@
}
__ mov(result.reg(),
FieldOperand(result.reg(), JSGlobalPropertyCell::kValueOffset));
- __ cmp(result.reg(), Factory::the_hole_value());
- deferred->Branch(equal);
+ bool is_dont_delete = false;
+ if (!info_->closure().is_null()) {
+ // When doing lazy compilation we can check if the global cell
+ // already exists and use its "don't delete" status as a hint.
+ AssertNoAllocation no_gc;
+ v8::internal::GlobalObject* global_object =
+ info_->closure()->context()->global();
+ LookupResult lookup;
+ global_object->LocalLookupRealNamedProperty(*name, &lookup);
+ if (lookup.IsProperty() && lookup.type() == NORMAL) {
+ ASSERT(lookup.holder() == global_object);
+ ASSERT(global_object->property_dictionary()->ValueAt(
+ lookup.GetDictionaryEntry())->IsJSGlobalPropertyCell());
+ is_dont_delete = lookup.IsDontDelete();
+ }
+ }
+ deferred->set_is_dont_delete(is_dont_delete);
+ if (!is_dont_delete) {
+ __ cmp(result.reg(), Factory::the_hole_value());
+ deferred->Branch(equal);
+ } else if (FLAG_debug_code) {
+ __ cmp(result.reg(), Factory::the_hole_value());
+ __ Check(not_equal, "DontDelete cells can't contain the hole");
+ }
__ IncrementCounter(&Counters::named_load_global_inline, 1);
+ if (is_dont_delete) {
+ __ IncrementCounter(&Counters::dont_delete_hint_hit, 1);
+ }
} else {
// The initial (invalid) offset has to be large enough to force a 32-bit
// instruction encoding to allow patching with an arbitrary offset. Use