Revision: 23373
Author: [email protected]
Date: Mon Aug 25 19:05:32 2014 UTC
Log: Version 3.28.71.5 (merged r23129, r23114)
Rewrite GetAccessor using the LookupIterator
Fix pointer iteration for maps.
[email protected]
BUG=
Review URL: https://codereview.chromium.org/471433006
https://code.google.com/p/v8/source/detail?r=23373
Modified:
/branches/3.28/src/heap/store-buffer.cc
/branches/3.28/src/objects.cc
/branches/3.28/src/version.cc
/branches/3.28/test/cctest/test-heap.cc
=======================================
--- /branches/3.28/src/heap/store-buffer.cc Tue Aug 12 06:42:13 2014 UTC
+++ /branches/3.28/src/heap/store-buffer.cc Mon Aug 25 19:05:32 2014 UTC
@@ -486,10 +486,11 @@
heap_object = iterator.Next()) {
// We skip free space objects.
if (!heap_object->IsFiller()) {
+ DCHECK(heap_object->IsMap());
FindPointersToNewSpaceInRegion(
- heap_object->address() + HeapObject::kHeaderSize,
- heap_object->address() + heap_object->Size(),
slot_callback,
- clear_maps);
+ heap_object->address() +
Map::kPointerFieldsBeginOffset,
+ heap_object->address() + Map::kPointerFieldsEndOffset,
+ slot_callback, clear_maps);
}
}
} else {
=======================================
--- /branches/3.28/src/objects.cc Thu Aug 14 08:46:03 2014 UTC
+++ /branches/3.28/src/objects.cc Mon Aug 25 19:05:32 2014 UTC
@@ -6864,14 +6864,6 @@
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
AssertNoContextChange ncc(isolate);
-
- // Check access rights if needed.
- if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return isolate->factory()->undefined_value();
- }
// Make the lookup and include prototypes.
uint32_t index = 0;
@@ -6879,11 +6871,20 @@
for (PrototypeIterator iter(isolate, object,
PrototypeIterator::START_AT_RECEIVER);
!iter.IsAtEnd(); iter.Advance()) {
- if (PrototypeIterator::GetCurrent(iter)->IsJSObject() &&
- JSObject::cast(*PrototypeIterator::GetCurrent(iter))
- ->HasDictionaryElements()) {
- JSObject* js_object =
- JSObject::cast(*PrototypeIterator::GetCurrent(iter));
+ Handle<Object> current = PrototypeIterator::GetCurrent(iter);
+ // Check access rights if needed.
+ if (current->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(Handle<JSObject>::cast(current), name,
+ v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(current),
+ v8::ACCESS_HAS);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ return isolate->factory()->undefined_value();
+ }
+
+ if (current->IsJSObject() &&
+ Handle<JSObject>::cast(current)->HasDictionaryElements()) {
+ JSObject* js_object = JSObject::cast(*current);
SeededNumberDictionary* dictionary =
js_object->element_dictionary();
int entry = dictionary->FindEntry(index);
if (entry != SeededNumberDictionary::kNotFound) {
@@ -6897,21 +6898,37 @@
}
}
} else {
- for (PrototypeIterator iter(isolate, object,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(); iter.Advance()) {
- LookupResult result(isolate);
- JSReceiver::cast(*PrototypeIterator::GetCurrent(iter))
- ->LookupOwn(name, &result);
- if (result.IsFound()) {
- if (result.IsReadOnly()) return
isolate->factory()->undefined_value();
- if (result.IsPropertyCallbacks()) {
- Object* obj = result.GetCallbackObject();
- if (obj->IsAccessorPair()) {
- return handle(AccessorPair::cast(obj)->GetComponent(component),
- isolate);
+ LookupIterator it(object, name, LookupIterator::SKIP_INTERCEPTOR);
+ for (; it.IsFound(); it.Next()) {
+ switch (it.state()) {
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::INTERCEPTOR:
+ UNREACHABLE();
+
+ case LookupIterator::ACCESS_CHECK:
+ if (it.HasAccess(v8::ACCESS_HAS)) continue;
+ isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
+ v8::ACCESS_HAS);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ return isolate->factory()->undefined_value();
+
+ case LookupIterator::JSPROXY:
+ return isolate->factory()->undefined_value();
+
+ case LookupIterator::PROPERTY:
+ if (!it.HasProperty()) continue;
+ switch (it.property_kind()) {
+ case LookupIterator::DATA:
+ continue;
+ case LookupIterator::ACCESSOR: {
+ Handle<Object> maybe_pair = it.GetAccessors();
+ if (maybe_pair->IsAccessorPair()) {
+ return handle(
+
AccessorPair::cast(*maybe_pair)->GetComponent(component),
+ isolate);
+ }
+ }
}
- }
}
}
}
=======================================
--- /branches/3.28/src/version.cc Mon Aug 18 12:16:05 2014 UTC
+++ /branches/3.28/src/version.cc Mon Aug 25 19:05:32 2014 UTC
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 28
#define BUILD_NUMBER 71
-#define PATCH_LEVEL 4
+#define PATCH_LEVEL 5
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.28/test/cctest/test-heap.cc Wed Aug 6 07:33:04 2014 UTC
+++ /branches/3.28/test/cctest/test-heap.cc Mon Aug 25 19:05:32 2014 UTC
@@ -4473,6 +4473,51 @@
// when it calls heap->AdjustLiveBytes(...).
JSObject::MigrateToMap(o, map2);
}
+
+
+TEST(RegressStoreBufferMapUpdate) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ Heap* heap = isolate->heap();
+
+ // This test checks that we do not treat instance size field of the map
+ // as a heap pointer when processing the store buffer.
+
+ Handle<Map> map1 = Map::Create(isolate->object_function(), 1);
+
+ // Allocate a throw-away object.
+ factory->NewFixedArray(1, NOT_TENURED);
+
+ // Allocate a new-space object that will be moved by the GC (because
+ // the throw-away object will die).
+ Handle<FixedArray> object_to_move = factory->NewFixedArray(1,
NOT_TENURED);
+
+ // Record the address before the GC.
+ Object* object_to_move_address = *object_to_move;
+
+ // Smash the new space pointer to the moving object into the instance
size
+ // field of the map. The idea is to trick the GC into updating this
pointer
+ // when the object moves. This would be wrong because instance size
should
+ // not be treated as a heap pointer.
+ *(reinterpret_cast<Object**>(map1->address() +
Map::kInstanceSizeOffset)) =
+ object_to_move_address;
+
+ // Make sure we scan the map's page on scavenge.
+ Page* page = Page::FromAddress(map1->address());
+ page->set_scan_on_scavenge(true);
+
+ heap->CollectGarbage(NEW_SPACE);
+
+ // Check the object has really moved.
+ CHECK(*object_to_move != object_to_move_address);
+
+ // Now check that we have not updated the instance size field of the map.
+ CHECK_EQ(object_to_move_address,
+ *(reinterpret_cast<Object**>(map1->address() +
+ Map::kInstanceSizeOffset)));
+}
#ifdef DEBUG
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.