Version 2.3.4
Fixed warnings on arm on newer GCC versions.
Fixed a number of minor bugs.
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@4453 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 315600b..11c4ac7 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -950,6 +950,26 @@
}
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+static Object* GenerateCheckPropertyCell(MacroAssembler* masm,
+ GlobalObject* global,
+ String* name,
+ Register scratch,
+ Label* miss) {
+ Object* probe = global->EnsurePropertyCell(name);
+ if (probe->IsFailure()) return probe;
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
+ ASSERT(cell->value()->IsTheHole());
+ __ mov(scratch, Immediate(Handle<Object>(cell)));
+ __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
+ Immediate(Factory::the_hole_value()));
+ __ j(not_equal, miss, not_taken);
+ return cell;
+}
+
+
#undef __
#define __ ACCESS_MASM(masm())
@@ -968,21 +988,19 @@
push_at_depth, miss);
// If we've skipped any global objects, it's not enough to verify
- // that their maps haven't changed.
+ // that their maps haven't changed. We also need to check that the
+ // property cell for the property is still empty.
while (object != holder) {
if (object->IsGlobalObject()) {
- GlobalObject* global = GlobalObject::cast(object);
- Object* probe = global->EnsurePropertyCell(name);
- if (probe->IsFailure()) {
- set_failure(Failure::cast(probe));
+ Object* cell = GenerateCheckPropertyCell(masm(),
+ GlobalObject::cast(object),
+ name,
+ scratch,
+ miss);
+ if (cell->IsFailure()) {
+ set_failure(Failure::cast(cell));
return result;
}
- JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
- ASSERT(cell->value()->IsTheHole());
- __ mov(scratch, Immediate(Handle<Object>(cell)));
- __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
- Immediate(Factory::the_hole_value()));
- __ j(not_equal, miss, not_taken);
}
object = JSObject::cast(object->GetPrototype());
}
@@ -1948,6 +1966,48 @@
}
+Object* LoadStubCompiler::CompileLoadNonexistent(String* name,
+ JSObject* object,
+ JSObject* last) {
+ // ----------- S t a t e -------------
+ // -- eax : receiver
+ // -- ecx : name
+ // -- esp[0] : return address
+ // -----------------------------------
+ Label miss;
+
+ // Check that the receiver isn't a smi.
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(zero, &miss, not_taken);
+
+ // Check the maps of the full prototype chain. Also check that
+ // global property cells up to (but not including) the last object
+ // in the prototype chain are empty.
+ CheckPrototypes(object, eax, last, ebx, edx, name, &miss);
+
+ // If the last object in the prototype chain is a global object,
+ // check that the global property cell is empty.
+ if (last->IsGlobalObject()) {
+ Object* cell = GenerateCheckPropertyCell(masm(),
+ GlobalObject::cast(last),
+ name,
+ edx,
+ &miss);
+ if (cell->IsFailure()) return cell;
+ }
+
+ // Return undefined if maps of the full prototype chain are still the
+ // same and no global property with this name contains a value.
+ __ mov(eax, Factory::undefined_value());
+ __ ret(0);
+
+ __ bind(&miss);
+ GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+ // Return the generated code.
+ return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
Object* LoadStubCompiler::CompileLoadField(JSObject* object,
JSObject* holder,