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