10a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 20a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// Redistribution and use in source and binary forms, with or without 30a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// modification, are permitted provided that the following conditions are 40a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// met: 50a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// 60a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// * Redistributions of source code must retain the above copyright 70a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// notice, this list of conditions and the following disclaimer. 80a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// * Redistributions in binary form must reproduce the above 90a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// copyright notice, this list of conditions and the following 100a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// disclaimer in the documentation and/or other materials provided 110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// with the distribution. 120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// * Neither the name of Google Inc. nor the names of its 130a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// contributors may be used to endorse or promote products derived 140a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// from this software without specific prior written permission. 150a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// 160a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 170a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 180a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 200a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 220a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 240a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 250a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 260a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 270a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h" 290a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgusing namespace v8::internal; 310a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 33f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgstatic void SetUpNewSpaceWithPoisonedMementoAtTop() { 340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 350a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Heap* heap = isolate->heap(); 360a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org NewSpace* new_space = heap->new_space(); 370a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 380a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Make sure we can allocate some objects without causing a GC later. 390a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 400a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Allocate a string, the GC may suspect a memento behind the string. 42255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<SeqOneByteString> string = 43255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org isolate->factory()->NewRawOneByteString(12).ToHandleChecked(); 440a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org CHECK(*string); 450a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 460a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Create an allocation memento behind the string with a garbage allocation 470a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // site pointer. 480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org AllocationMemento* memento = 490a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org reinterpret_cast<AllocationMemento*>(new_space->top() + kHeapObjectTag); 500a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org memento->set_map_no_write_barrier(heap->allocation_memento_map()); 510a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org memento->set_allocation_site( 520a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org reinterpret_cast<AllocationSite*>(kHeapObjectTag), SKIP_WRITE_BARRIER); 53f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 54f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 55f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 56f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgTEST(Regress340063) { 57f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CcTest::InitializeVM(); 58f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!i::FLAG_allocation_site_pretenuring) return; 59f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org v8::HandleScope scope(CcTest::isolate()); 60f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 61f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 62f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetUpNewSpaceWithPoisonedMementoAtTop(); 630a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 640a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Call GC to see if we can handle a poisonous memento right after the 650a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // current new space top pointer. 66f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CcTest::i_isolate()->heap()->CollectAllGarbage( 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Heap::kAbortIncrementalMarkingMask); 68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 69f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 70f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 71f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgTEST(BadMementoAfterTopForceScavenge) { 72f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CcTest::InitializeVM(); 73f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!i::FLAG_allocation_site_pretenuring) return; 74f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org v8::HandleScope scope(CcTest::isolate()); 75f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 76f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetUpNewSpaceWithPoisonedMementoAtTop(); 77f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 78f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Force GC to test the poisoned memento handling 79f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CcTest::i_isolate()->heap()->CollectGarbage(i::NEW_SPACE); 800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org} 8169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 8269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 8369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.orgTEST(PretenuringCallNew) { 8469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org CcTest::InitializeVM(); 8569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (!i::FLAG_allocation_site_pretenuring) return; 8669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (!i::FLAG_pretenuring_call_new) return; 8769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 8869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org v8::HandleScope scope(CcTest::isolate()); 8969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 9069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Heap* heap = isolate->heap(); 9169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 9269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org int call_count = 10; 9369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org i::ScopedVector<char> test_buf(1024); 9469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org const char* program = 9569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org "function f() {" 9669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org " this.a = 3;" 9769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org " this.b = {};" 9869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org " return this;" 9969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org "};" 10069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org "var a;" 10169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org "for(var i = 0; i < %d; i++) {" 10269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org " a = new f();" 10369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org "}" 10469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org "a;"; 10570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org i::SNPrintF(test_buf, program, call_count); 10669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org v8::Local<v8::Value> res = CompileRun(test_buf.start()); 10769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Handle<JSObject> o = 10869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); 10969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 11069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // The object of class f should have a memento secreted behind it. 11169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Address memento_address = o->address() + o->map()->instance_size(); 11269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AllocationMemento* memento = 11369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org reinterpret_cast<AllocationMemento*>(memento_address + kHeapObjectTag); 11469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org CHECK_EQ(memento->map(), heap->allocation_memento_map()); 11569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 11669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Furthermore, how many mementos did we create? The count should match 117011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org // call_count. Note, that mementos are allocated during the inobject slack 118011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org // tracking phase. 11969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AllocationSite* site = memento->GetAllocationSite(); 120011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org CHECK_EQ(call_count, site->pretenure_create_count()->value()); 12169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org} 122