Index: test/cctest/test-unboxed-doubles.cc |
diff --git a/test/cctest/test-unboxed-doubles.cc b/test/cctest/test-unboxed-doubles.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3dd2769933f85847fb98bfe0d7b3b84eeda4b101 |
--- /dev/null |
+++ b/test/cctest/test-unboxed-doubles.cc |
@@ -0,0 +1,109 @@ |
+// Copyright 2014 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: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following |
+// disclaimer in the documentation and/or other materials provided |
+// with the distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived |
+// from this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+#include <stdlib.h> |
+#include <utility> |
+ |
+#include "src/v8.h" |
+ |
+#include "src/compilation-cache.h" |
+#include "src/execution.h" |
+#include "src/factory.h" |
+#include "src/global-handles.h" |
+#include "src/ic/ic.h" |
+#include "src/macro-assembler.h" |
+#include "test/cctest/cctest.h" |
+ |
+using namespace v8::internal; |
+ |
+#if (V8_DOUBLE_FIELDS_UNBOXING) |
+ |
+TEST(TestStoreBufferScanOnScavenge) { |
+ CcTest::InitializeVM(); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Factory* factory = isolate->factory(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ |
+ CompileRun( |
+ "function A() {" |
+ " this.x = 42.5;" |
+ " this.o = {};" |
+ "};" |
+ "var o = new A();"); |
+ |
+ Handle<String> obj_name = factory->InternalizeUtf8String("o"); |
+ |
+ Handle<Object> obj_value = |
+ Object::GetProperty(isolate->global_object(), obj_name).ToHandleChecked(); |
+ CHECK(obj_value->IsJSObject()); |
+ Handle<JSObject> obj = Handle<JSObject>::cast(obj_value); |
+ |
+ { |
+ // Ensure the object is properly set up. |
+ Map* map = obj->map(); |
+ DescriptorArray* descriptors = map->instance_descriptors(); |
+ CHECK(map->NumberOfOwnDescriptors() == 2); |
+ CHECK(descriptors->GetDetails(0).representation().IsDouble()); |
+ CHECK(descriptors->GetDetails(1).representation().IsHeapObject()); |
+ FieldIndex field_index = FieldIndex::ForDescriptor(map, 0); |
+ CHECK(field_index.is_inobject() && field_index.is_double()); |
+ CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index)); |
+ if (FLAG_unbox_double_fields) { |
+ CHECK_EQ(42.5, obj->RawFastDoublePropertyAt(field_index)); |
+ } |
+ } |
+ CHECK(isolate->heap()->new_space()->Contains(*obj)); |
+ |
+ // Trigger GCs so that the newly allocated object moves to old gen. |
+ SimulateFullSpace(CcTest::heap()->old_pointer_space()); |
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
+ |
+ CHECK(isolate->heap()->old_pointer_space()->Contains(*obj)); |
+ |
+ // Create temp object in the new space. |
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED); |
+ CHECK(isolate->heap()->new_space()->Contains(*temp)); |
+ |
+ // Construct a double value that looks like a pointer to the new space object |
+ // and store it into the obj. |
+ Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize; |
+ double boom_value = bit_cast<double>(fake_object); |
+ |
+ FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0); |
+ obj->FastPropertyAtPut(field_index, |
+ *factory->NewHeapNumber(boom_value, MUTABLE)); |
+ |
+ // Enforce scan on scavenge for the obj's page. |
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
+ chunk->set_scan_on_scavenge(true); |
+ |
+ // Trigger GCs and force evacuation. Should not crash there. |
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
+} |
+ |
+#endif |