13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h> 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "execution.h" 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "factory.h" 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h" 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "global-handles.h" 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cctest.h" 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Persistent<v8::Context> env; 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitializeVM() { 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (env.IsEmpty()) env = v8::Context::New(); 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Enter(); 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckMap(Map* map, int type, int instance_size) { 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(map->IsHeapObject()); 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->Contains(map)); 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(HEAP->meta_map(), map->map()); 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(type, map->instance_type()); 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(instance_size, map->instance_size()); 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(HeapMaps) { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckMap(HEAP->meta_map(), MAP_TYPE, Map::kSize); 3844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckMap(HEAP->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); 3944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckMap(HEAP->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); 4044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckMap(HEAP->string_map(), STRING_TYPE, kVariableSizeSentinel); 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckOddball(Object* obj, const char* string) { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(obj->IsOddball()); 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool exc; 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc); 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckSmi(int value, const char* string) { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool exc; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* print_string = 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *Execution::ToString(Handle<Object>(Smi::FromInt(value)), &exc); 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckNumber(double value, const char* string) { 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked(); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(obj->IsNumber()); 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool exc; 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc); 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckFindCodeObject() { 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test FindCodeObject 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm. 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Assembler assm(Isolate::Current(), NULL, 0); 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ nop(); // supported on all architectures 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* code = HEAP->CreateCode( 805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck desc, 815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::ComputeFlags(Code::STUB), 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(code->IsCode()); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject* obj = HeapObject::cast(code); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address obj_addr = obj->address(); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < obj->Size(); i += kPointerSize) { 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* found = HEAP->FindCodeObject(obj_addr + i); 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(code, found); 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* copy = HEAP->CreateCode( 945913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck desc, 955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::ComputeFlags(Code::STUB), 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(copy->IsCode()); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject* obj_copy = HeapObject::cast(copy); 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* not_right = HEAP->FindCodeObject(obj_copy->address() + 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj_copy->Size() / 2); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(not_right != code); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(HeapObjects) { 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* value = HEAP->NumberFromDouble(1.000123)->ToObjectChecked(); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsHeapNumber()); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1.000123, value->Number()); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block value = HEAP->NumberFromDouble(1.0)->ToObjectChecked(); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsSmi()); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1.0, value->Number()); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block value = HEAP->NumberFromInt32(1024)->ToObjectChecked(); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsSmi()); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1024.0, value->Number()); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block value = HEAP->NumberFromInt32(Smi::kMinValue)->ToObjectChecked(); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsSmi()); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value()); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block value = HEAP->NumberFromInt32(Smi::kMaxValue)->ToObjectChecked(); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsSmi()); 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value()); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifndef V8_TARGET_ARCH_X64 1353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // TODO(lrn): We need a NumberFromIntptr function in order to test this. 13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block value = HEAP->NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked(); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsHeapNumber()); 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number()); 1403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* maybe_value = 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); 1445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck value = maybe_value->ToObjectChecked(); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsHeapNumber()); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(value->IsNumber()); 1473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), 1483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block value->Number()); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // nan oddball checks 15144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->nan_value()->IsNumber()); 15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(isnan(HEAP->nan_value()->Number())); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> s = FACTORY->NewStringFromAscii(CStrVector("fisk hest ")); 1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(s->IsString()); 1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(10, s->length()); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15844f0eee88ff00398ff7f715fab053374d808c90dSteve Block String* object_symbol = String::cast(HEAP->Object_symbol()); 15944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK( 16044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->context()->global()->HasLocalProperty(object_symbol)); 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check ToString for oddballs 16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckOddball(HEAP->true_value(), "true"); 16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckOddball(HEAP->false_value(), "false"); 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckOddball(HEAP->null_value(), "null"); 16644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckOddball(HEAP->undefined_value(), "undefined"); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check ToString for Smis 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckSmi(0, "0"); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckSmi(42, "42"); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckSmi(-42, "-42"); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check ToString for Numbers 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckNumber(1.1, "1.1"); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckFindCodeObject(); 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Tagging) { 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int request = 24; 1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Smi::FromInt(42)->IsSmi()); 185f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure()); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NEW_SPACE, 187f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Failure::RetryAfterGC(NEW_SPACE)->allocation_space()); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(OLD_POINTER_SPACE, 189f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space()); 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Failure::Exception()->IsFailure()); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GarbageCollection) { 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check GC. 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(NEW_SPACE); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction"); 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot"); 20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> prop_namex = FACTORY->LookupAsciiSymbol("theSlotx"); 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> obj_name = FACTORY->LookupAsciiSymbol("theObject"); 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::HandleScope inner_scope; 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Allocate a function and keep it in global object's property. 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> function = 21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewFunction(name, FACTORY->undefined_value()); 2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Map> initial_map = 21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function->set_initial_map(*initial_map); 21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->context()->global()->SetProperty( 217e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *name, *function, NONE, kNonStrictMode)->ToObjectChecked(); 2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Allocate an object. Unrooted after leaving the scope. 21944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> obj = FACTORY->NewJSObject(function); 220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 221e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); 222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 223e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *prop_namex, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked(); 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); 2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); 2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(NEW_SPACE); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Function should be alive. 23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*name)); 2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check function is retained. 23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* func_value = Isolate::Current()->context()->global()-> 23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(*name)->ToObjectChecked(); 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(func_value->IsJSFunction()); 2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> function(JSFunction::cast(func_value)); 2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HandleScope inner_scope; 2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Allocate another object, make it reachable from global. 24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> obj = FACTORY->NewJSObject(function); 24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->context()->global()->SetProperty( 244e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked(); 245e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); 2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // After gc, it should survive. 25044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(NEW_SPACE); 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*obj_name)); 25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->context()->global()-> 25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(*obj_name)->ToObjectChecked()->IsJSObject()); 25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = Isolate::Current()->context()->global()-> 25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(*obj_name)->ToObjectChecked(); 2575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSObject* js_obj = JSObject::cast(obj); 2585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name)); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void VerifyStringAllocation(const char* string) { 2636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::HandleScope scope; 26444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> s = FACTORY->NewStringFromUtf8(CStrVector(string)); 265d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(string), s->length()); 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int index = 0; index < s->length(); index++) { 2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index)); 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(String) { 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VerifyStringAllocation("a"); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VerifyStringAllocation("ab"); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VerifyStringAllocation("abc"); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VerifyStringAllocation("abcd"); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VerifyStringAllocation("fiskerdrengen er paa havet"); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(LocalHandles) { 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* name = "Kasper the spunky"; 28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> string = FACTORY->NewStringFromAscii(CStrVector(name)); 289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(name), string->length()); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GlobalHandles) { 294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InitializeVM(); 29569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GlobalHandles* global_handles = Isolate::Current()->global_handles(); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h1; 2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h2; 2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h3; 3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h4; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HandleScope scope; 3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); 30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> u = FACTORY->NewNumber(1.12344); 3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block h1 = global_handles->Create(*i); 30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block h2 = global_handles->Create(*u); 31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block h3 = global_handles->Create(*i); 31144f0eee88ff00398ff7f715fab053374d808c90dSteve Block h4 = global_handles->Create(*u); 3126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // after gc, it should survive 31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(NEW_SPACE); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h1)->IsString()); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h2)->IsHeapNumber()); 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h3)->IsString()); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h4)->IsHeapNumber()); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(*h3, *h1); 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h1.location()); 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h3.location()); 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(*h4, *h2); 32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h2.location()); 32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h4.location()); 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool WeakPointerCleared = false; 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle, 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* id) { 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; 33750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen handle.Dispose(); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(WeakGlobalHandlesScavenge) { 342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InitializeVM(); 34369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GlobalHandles* global_handles = Isolate::Current()->global_handles(); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WeakPointerCleared = false; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h1; 3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h2; 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HandleScope scope; 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); 35444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> u = FACTORY->NewNumber(1.12344); 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block h1 = global_handles->Create(*i); 35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block h2 = global_handles->Create(*u); 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(h2.location(), 36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 36244f0eee88ff00398ff7f715fab053374d808c90dSteve Block &TestWeakGlobalHandleCallback); 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scavenge treats weak pointers as normal roots. 36544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h1)->IsString()); 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h2)->IsHeapNumber()); 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!WeakPointerCleared); 37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!global_handles->IsNearDeath(h2.location())); 37244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!global_handles->IsNearDeath(h1.location())); 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h1.location()); 37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h2.location()); 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(WeakGlobalHandlesMark) { 380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InitializeVM(); 38169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GlobalHandles* global_handles = Isolate::Current()->global_handles(); 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WeakPointerCleared = false; 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h1; 3866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h2; 3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HandleScope scope; 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); 39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> u = FACTORY->NewNumber(1.12344); 3936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block h1 = global_handles->Create(*i); 39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block h2 = global_handles->Create(*u); 3966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(NEW_SPACE); 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the object is promoted. 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(h2.location(), 40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block &TestWeakGlobalHandleCallback); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!GlobalHandles::IsNearDeath(h1.location())); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!GlobalHandles::IsNearDeath(h2.location())); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK((*h1)->IsString()); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(WeakPointerCleared); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!GlobalHandles::IsNearDeath(h1.location())); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(h1.location()); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DeleteWeakGlobalHandle) { 419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InitializeVM(); 42069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GlobalHandles* global_handles = Isolate::Current()->global_handles(); 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block WeakPointerCleared = false; 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> h; 4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 4276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HandleScope scope; 4286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); 43044f0eee88ff00398ff7f715fab053374d808c90dSteve Block h = global_handles->Create(*i); 4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(h.location(), 43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block &TestWeakGlobalHandleCallback); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scanvenge does not recognize weak reference. 43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!WeakPointerCleared); 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark-compact treats weak reference properly. 44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(WeakPointerCleared); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* not_so_random_string_table[] = { 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "abstract", 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "boolean", 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "break", 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "byte", 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "case", 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "catch", 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "char", 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "class", 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "const", 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "continue", 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debugger", 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "default", 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "delete", 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "do", 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "double", 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "else", 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "enum", 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "export", 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "extends", 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "false", 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "final", 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "finally", 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "float", 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "for", 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function", 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "goto", 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "if", 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "implements", 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "import", 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "in", 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instanceof", 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "int", 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "interface", 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "long", 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "native", 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "new", 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "null", 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "package", 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "private", 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "protected", 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "public", 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "return", 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "short", 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "static", 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "super", 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "switch", 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "synchronized", 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "this", 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "throw", 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "throws", 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "transient", 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "true", 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "try", 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "typeof", 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var", 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "void", 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "volatile", 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "while", 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "with", 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckSymbols(const char** strings) { 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (const char* string = *strings; *strings != 0; string = *strings++) { 5145913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* a; 51544f0eee88ff00398ff7f715fab053374d808c90dSteve Block MaybeObject* maybe_a = HEAP->LookupAsciiSymbol(string); 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // LookupAsciiSymbol may return a failure if a GC is needed. 5175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe_a->ToObject(&a)) continue; 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(a->IsSymbol()); 5195913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* b; 52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block MaybeObject* maybe_b = HEAP->LookupAsciiSymbol(string); 5215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe_b->ToObject(&b)) continue; 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(b, a); 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(String::cast(b)->IsEqualTo(CStrVector(string))); 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SymbolTable) { 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckSymbols(not_so_random_string_table); 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckSymbols(not_so_random_string_table); 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(FunctionAllocation) { 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 54044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction"); 5416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> function = 54244f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewFunction(name, FACTORY->undefined_value()); 5436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Map> initial_map = 54444f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 5456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function->set_initial_map(*initial_map); 5466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 54744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot"); 54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> obj = FACTORY->NewJSObject(function); 549e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 550e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); 5516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that we can add properties to function objects. 553e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch function->SetProperty( 554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *prop_name, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked(); 5556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ObjectProperties) { 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block String* object_symbol = String::cast(HEAP->Object_symbol()); 56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* raw_object = Isolate::Current()->context()->global()-> 56544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(object_symbol)->ToObjectChecked(); 5665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSFunction* object_function = JSFunction::cast(raw_object); 5676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> constructor(object_function); 56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> obj = FACTORY->NewJSObject(constructor); 56944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> first = FACTORY->LookupAsciiSymbol("first"); 57044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> second = FACTORY->LookupAsciiSymbol("second"); 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // check for empty 5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!obj->HasLocalProperty(*first)); 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add first 576e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 577e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 5786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*first)); 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // delete first 5816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); 5826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!obj->HasLocalProperty(*first)); 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add first and then second 585e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 586e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 587e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 588e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); 5896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*first)); 5906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*second)); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // delete first and then second 5936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); 5946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*second)); 5956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); 5966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!obj->HasLocalProperty(*first)); 5976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!obj->HasLocalProperty(*second)); 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add first and then second 600e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 601e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 602e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); 6046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*first)); 6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*second)); 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // delete second and then first 6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); 6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*first)); 6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); 6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!obj->HasLocalProperty(*first)); 6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!obj->HasLocalProperty(*second)); 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // check string and symbol match 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* string1 = "fisk"; 61644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> s1 = FACTORY->NewStringFromAscii(CStrVector(string1)); 617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 61944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> s1_symbol = FACTORY->LookupAsciiSymbol(string1); 6206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*s1_symbol)); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // check symbol and string match 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* string2 = "fugl"; 62444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> s2_symbol = FACTORY->LookupAsciiSymbol(string2); 625e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 626e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *s2_symbol, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 62744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> s2 = FACTORY->NewStringFromAscii(CStrVector(string2)); 6286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(obj->HasLocalProperty(*s2)); 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(JSObjectMaps) { 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 63644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction"); 6376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> function = 63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewFunction(name, FACTORY->undefined_value()); 6396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Map> initial_map = 64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 6416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function->set_initial_map(*initial_map); 6426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 64344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot"); 64444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> obj = FACTORY->NewJSObject(function); 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a propery 647e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 648e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); 6496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the map has changed 6526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(*initial_map != obj->map()); 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(JSArray) { 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> name = FACTORY->LookupAsciiSymbol("Array"); 66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* raw_object = Isolate::Current()->context()->global()-> 66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(*name)->ToObjectChecked(); 6636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> function = Handle<JSFunction>( 6645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSFunction::cast(raw_object)); 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate the object. 66744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> object = FACTORY->NewJSObject(function); 6686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSArray> array = Handle<JSArray>::cast(object); 66980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // We just initialized the VM, no heap allocation failure yet. 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->Initialize(0)->ToObjectChecked(); 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set array length to 0. 6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->SetElementsLength(Smi::FromInt(0))->ToObjectChecked(); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(Smi::FromInt(0), array->length()); 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Must be in fast mode. 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(array->HasFastTypeElements()); 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // array[length] = name. 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->SetElement(0, *name, NONE, kNonStrictMode)->ToObjectChecked(); 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(Smi::FromInt(1), array->length()); 6816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(array->GetElement(0), *name); 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Set array length with larger than smi value. 6846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> length = 68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1); 6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->SetElementsLength(*length)->ToObjectChecked(); 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t int_length = 0; 6897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK(length->ToArrayIndex(&int_length)); 6906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(*length, array->length()); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(array->HasDictionaryElements()); // Must be in slow mode. 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // array[length] = name. 6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->SetElement(int_length, *name, NONE, kNonStrictMode)->ToObjectChecked(); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t new_int_length = 0; 6967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK(array->length()->ToArrayIndex(&new_int_length)); 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); 6986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(array->GetElement(int_length), *name); 6996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(array->GetElement(0), *name); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(JSObjectCopy) { 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block String* object_symbol = String::cast(HEAP->Object_symbol()); 70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* raw_object = Isolate::Current()->context()->global()-> 70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(object_symbol)->ToObjectChecked(); 7105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSFunction* object_function = JSFunction::cast(raw_object); 7116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSFunction> constructor(object_function); 71244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> obj = FACTORY->NewJSObject(constructor); 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> first = FACTORY->LookupAsciiSymbol("first"); 71444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> second = FACTORY->LookupAsciiSymbol("second"); 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 716e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 717e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 718e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty( 719e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked(); 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make the clone. 7256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSObject> clone = Copy(obj); 7266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(!clone.is_identical_to(obj)); 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(obj->GetElement(0), clone->GetElement(0)); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(obj->GetElement(1), clone->GetElement(1)); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first)); 7326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Flip the values. 735e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch clone->SetProperty( 736e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *first, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); 737e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch clone->SetProperty( 738e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked(); 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked(); 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(obj->GetElement(1), clone->GetElement(0)); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(obj->GetElement(0), clone->GetElement(1)); 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first)); 7476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second)); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StringAllocation) { 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 }; 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int length = 0; length < 100; length++) { 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* non_ascii = NewArray<char>(3 * length + 1); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* ascii = NewArray<char>(length + 1); 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block non_ascii[3 * length] = 0; 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ascii[length] = 0; 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < length; i++) { 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ascii[i] = 'a'; 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block non_ascii[3 * i] = chars[0]; 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block non_ascii[3 * i + 1] = chars[1]; 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block non_ascii[3 * i + 2] = chars[2]; 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> non_ascii_sym = 76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->LookupSymbol(Vector<const char>(non_ascii, 3 * length)); 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(length, non_ascii_sym->length()); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> ascii_sym = 77244f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->LookupSymbol(Vector<const char>(ascii, length)); 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(length, ascii_sym->length()); 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> non_ascii_str = 77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewStringFromUtf8(Vector<const char>(non_ascii, 3 * length)); 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block non_ascii_str->Hash(); 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(length, non_ascii_str->length()); 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> ascii_str = 77944f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewStringFromUtf8(Vector<const char>(ascii, length)); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ascii_str->Hash(); 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(length, ascii_str->length()); 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(non_ascii); 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(ascii); 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int ObjectsFoundInHeap(Handle<Object> objs[], int size) { 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of objects found in the heap. 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int found_count = 0; 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapIterator iterator; 792d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < size; i++) { 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*objs[i] == obj) { 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block found_count++; 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return found_count; 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Iteration) { 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Array of objects to scan haep for. 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int objs_count = 6; 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> objs[objs_count]; 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int next_objs_index = 0; 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE 81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block objs[next_objs_index++] = FACTORY->NewJSArray(10); 8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch objs[next_objs_index++] = FACTORY->NewJSArray(10, FAST_ELEMENTS, TENURED); 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate a small string to OLD_DATA_SPACE and NEW_SPACE 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block objs[next_objs_index++] = 81844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewStringFromAscii(CStrVector("abcdefghij")); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block objs[next_objs_index++] = 82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED); 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate a large string (for large object space). 8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int large_size = Page::kMaxNonCodeHeapObjectSize + 1; 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* str = new char[large_size]; 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < large_size - 1; ++i) str[i] = 'a'; 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block str[large_size - 1] = '\0'; 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block objs[next_objs_index++] = 82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewStringFromAscii(CStrVector(str), TENURED); 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete[] str; 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add a Map object to look for. 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(objs_count, next_objs_index); 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 8376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8396ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(EmptyHandleEscapeFrom) { 8406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block InitializeVM(); 8416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::HandleScope scope; 8436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSObject> runaway; 8446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block { 8466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::HandleScope nested; 8476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSObject> empty; 8486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block runaway = empty.EscapeFrom(&nested); 8496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 8506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(runaway.is_null()); 8526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 8536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8556ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic int LenFromSize(int size) { 8566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return (size - FixedArray::kHeaderSize) / kPointerSize; 8576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 8586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8606ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(Regression39128) { 8616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Test case for crbug.com/39128. 8626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block InitializeVM(); 8636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Increase the chance of 'bump-the-pointer' allocation in old space. 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 8666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::HandleScope scope; 8686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // The plan: create JSObject which references objects in new space. 8706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Then clone this object (forcing it to go into old space) and check 8717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // that region dirty marks are updated correctly. 8726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Step 1: prepare a map for the object. We add 1 inobject property to it. 87444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSFunction> object_ctor( 87544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->global_context()->object_function()); 8766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(object_ctor->has_initial_map()); 8776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Map> object_map(object_ctor->initial_map()); 8786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Create a map with single inobject property. 87944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Map> my_map = FACTORY->CopyMap(object_map, 1); 8806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int n_properties = my_map->inobject_properties(); 8816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_GT(n_properties, 0); 8826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int object_size = my_map->instance_size(); 8846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Step 2: allocate a lot of objects so to almost fill new space: we need 8866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // just enough room to allocate JSObject and thus fill the newspace. 8876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int allocation_amount = Min(FixedArray::kMaxSize, 88944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->MaxObjectSizeInNewSpace()); 8906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int allocation_len = LenFromSize(allocation_amount); 89144f0eee88ff00398ff7f715fab053374d808c90dSteve Block NewSpace* new_space = HEAP->new_space(); 8926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Address* top_addr = new_space->allocation_top_address(); 8936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Address* limit_addr = new_space->allocation_limit_address(); 8946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while ((*limit_addr - *top_addr) > allocation_amount) { 89544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!HEAP->always_allocate()); 89644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* array = HEAP->AllocateFixedArray(allocation_len)->ToObjectChecked(); 89744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!array->IsFailure()); 8986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(new_space->Contains(array)); 8996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 9006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 9016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Step 3: now allocate fixed array and JSObject to fill the whole new space. 9026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size); 9036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int fixed_array_len = LenFromSize(to_fill); 9046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(fixed_array_len < FixedArray::kMaxLength); 9056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 90644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!HEAP->always_allocate()); 90744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* array = HEAP->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); 90844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!array->IsFailure()); 9096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(new_space->Contains(array)); 9106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 91144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* object = HEAP->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); 9126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK(new_space->Contains(object)); 9136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSObject* jsobject = JSObject::cast(object); 9147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); 9156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(0, jsobject->properties()->length()); 9166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Create a reference to object in new space in jsobject. 9176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block jsobject->FastPropertyAtPut(-1, array); 9186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 9196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); 9206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 9216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Step 4: clone jsobject, but force always allocate first to create a clone 9226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // in old pointer space. 92344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address old_pointer_space_top = HEAP->old_pointer_space()->top(); 9246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block AlwaysAllocateScope aa_scope; 92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked(); 9266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSObject* clone = JSObject::cast(clone_obj); 9276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (clone->address() != old_pointer_space_top) { 9286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Alas, got allocated from free list, we cannot do checks. 9296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return; 9306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 93144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->old_pointer_space()->Contains(clone->address())); 9327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 9337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 934f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 9357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(TestCodeFlushing) { 9367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch i::FLAG_allow_natives_syntax = true; 9377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If we do not flush code this test is invalid. 9387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (!FLAG_flush_code) return; 9397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch InitializeVM(); 9407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 9417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* source = "function foo() {" 9427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var x = 42;" 9437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var y = 42;" 9447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var z = x + y;" 9457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch "};" 9467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch "foo()"; 94744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); 9487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // This compile will add the code to the compilation cache. 950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { v8::HandleScope scope; 951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(source); 952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check function is compiled. 95544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* func_value = Isolate::Current()->context()->global()-> 95644f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(*foo_name)->ToObjectChecked(); 9577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK(func_value->IsJSFunction()); 9587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<JSFunction> function(JSFunction::cast(func_value)); 9597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK(function->shared()->is_compiled()); 9607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(1609) Currently incremental marker does not support code flushing. 9623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK(function->shared()->is_compiled()); 966756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 9737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // foo should no longer be in the compilation cache 975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!function->is_compiled() || function->IsOptimized()); 9777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Call foo to get it recompiled. 9787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CompileRun("foo()"); 9797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK(function->shared()->is_compiled()); 980756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK(function->is_compiled()); 9816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 982f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 983f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 984f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// Count the number of global contexts in the weak list of global contexts. 985f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic int CountGlobalContexts() { 986f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch int count = 0; 98744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* object = HEAP->global_contexts_list(); 988f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch while (!object->IsUndefined()) { 989f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch count++; 990f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); 991f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 992f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return count; 993f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 994f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 995f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Count the number of user functions in the weak list of optimized 997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// functions attached to a global context. 998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { 999b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count = 0; 1000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Context> icontext = v8::Utils::OpenHandle(*context); 1001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); 1002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { 1003b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch count++; 1004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch object = JSFunction::cast(object)->next_function_link(); 1005b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return count; 1007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1010f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(TestInternalWeakLists) { 101144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::V8::Initialize(); 101244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1013f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static const int kNumTestContexts = 10; 1014f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1015f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::HandleScope scope; 1016f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Persistent<v8::Context> ctx[kNumTestContexts]; 1017f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1018f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(0, CountGlobalContexts()); 1019f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1020f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Create a number of global contests which gets linked together. 1021f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i < kNumTestContexts; i++) { 1022f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ctx[i] = v8::Context::New(); 1023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); 1025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1026f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(i + 1, CountGlobalContexts()); 1027f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1028f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ctx[i]->Enter(); 1029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a handle scope so no function objects get stuch in the outer 1031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // handle scope 1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 1033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* source = "function f1() { };" 1034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f2() { };" 1035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f3() { };" 1036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f4() { };" 1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f5() { };"; 1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(source); 1039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); 1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f1()"); 1041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i])); 1042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f2()"); 1043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); 1044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f3()"); 1045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f4()"); 1047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f5()"); 1049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); 1050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Remove function f1, and 1052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f1=null"); 1053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Scavenge treats these references as strong. 1055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < 10; j++) { 105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 1057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); 1058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Mark compact handles the weak references. 10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get rid of f3 and f5 in the same way. 1065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f3=null"); 1066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < 10; j++) { 106744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 1068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f5=null"); 1073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < 10; j++) { 107444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 1075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); 1079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1080f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ctx[i]->Exit(); 1081f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1082f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1083f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Force compilation cache cleanup. 10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1085f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1086f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Dispose the global contexts one by one. 1087f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i < kNumTestContexts; i++) { 1088f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ctx[i].Dispose(); 1089f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ctx[i].Clear(); 1090f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1091f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Scavenge treats these references as strong. 1092f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int j = 0; j < 10; j++) { 109344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 1094f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); 1095f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1096f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1097f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Mark compact handles the weak references. 10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1099f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); 1100f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1101f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1102f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(0, CountGlobalContexts()); 1103f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 1104f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1105f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1106f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// Count the number of global contexts in the weak list of global contexts 1107f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// causing a GC after the specified number of elements. 1108f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic int CountGlobalContextsWithGC(int n) { 1109f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch int count = 0; 111044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> object(HEAP->global_contexts_list()); 1111f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch while (!object->IsUndefined()) { 1112f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch count++; 11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1114f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch object = 1115f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); 1116f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1117f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return count; 1118f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 1119f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1120f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Count the number of user functions in the weak list of optimized 1122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// functions attached to a global context causing a GC after the 1123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// specified number of elements. 1124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, 1125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int n) { 1126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int count = 0; 1127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Context> icontext = v8::Utils::OpenHandle(*context); 1128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); 1129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (object->IsJSFunction() && 1130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch !Handle<JSFunction>::cast(object)->IsBuiltin()) { 1131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch count++; 11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch object = Handle<Object>( 1134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object::cast(JSFunction::cast(*object)->next_function_link())); 1135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return count; 1137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1140f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(TestInternalWeakListsTraverseWithGC) { 114144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::V8::Initialize(); 114244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1143f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static const int kNumTestContexts = 10; 1144f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1145f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::HandleScope scope; 1146f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Persistent<v8::Context> ctx[kNumTestContexts]; 1147f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1148f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(0, CountGlobalContexts()); 1149f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1150f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Create an number of contexts and check the length of the weak list both 1151f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // with and without GCs while iterating the list. 1152f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i < kNumTestContexts; i++) { 1153f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ctx[i] = v8::Context::New(); 1154f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(i + 1, CountGlobalContexts()); 1155f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); 1156f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); 1159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile a number of functions the length of the weak list of optimized 1161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // functions both with and without GCs while iterating the list. 1162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ctx[0]->Enter(); 1163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* source = "function f1() { };" 1164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f2() { };" 1165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f3() { };" 1166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f4() { };" 1167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f5() { };"; 1168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(source); 1169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); 1170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f1()"); 1171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0])); 1172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); 1173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f2()"); 1174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0])); 1175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); 1176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f3()"); 1177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0])); 1178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); 1179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f4()"); 1180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0])); 1181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); 1182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f5()"); 1183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); 1184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); 1185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ctx[0]->Exit(); 1187f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 11888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 11898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 11903ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(TestSizeOfObjects) { 11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::V8::Initialize(); 11923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get initial heap size after several full GCs, which will stabilize 11943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the heap size and return with sweeping finished completely. 11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 11973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 11983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 11993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(HEAP->old_pointer_space()->IsSweepingComplete()); 12003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int initial_size = static_cast<int>(HEAP->SizeOfObjects()); 12013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 12033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Allocate objects on several different old-space pages so that 12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // lazy sweeping kicks in for subsequent GC runs. 12053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AlwaysAllocateScope always_allocate; 12063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); 12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 1; i <= 100; i++) { 12083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); 12093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(initial_size + i * filler_size, 12103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(HEAP->SizeOfObjects())); 12113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The heap size should go back to initial size after a full GC, even 12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // though sweeping didn't finish yet. 12163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 12173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(!HEAP->old_pointer_space()->IsSweepingComplete()); 12183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); 12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Advancing the sweeper step-wise should not change the heap size. 12213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!HEAP->old_pointer_space()->IsSweepingComplete()) { 12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->old_pointer_space()->AdvanceSweeper(KB); 12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); 12243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) WangTEST(TestSizeOfObjectsVsHeapIteratorPrecision) { 12298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang InitializeVM(); 12303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->EnsureHeapIsIterable(); 123144f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); 12323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapIterator iterator; 12338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang intptr_t size_of_objects_2 = 0; 12348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang for (HeapObject* obj = iterator.next(); 12358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang obj != NULL; 12368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang obj = iterator.next()) { 12378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang size_of_objects_2 += obj->Size(); 12388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 12393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Delta must be within 5% of the larger result. 12403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(gc): Tighten this up by distinguishing between byte 12413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // arrays that are real and those that merely mark free space 12423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // on the heap. 12438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (size_of_objects_1 > size_of_objects_2) { 12448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang intptr_t delta = size_of_objects_1 - size_of_objects_2; 12458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 12468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "Iterator: %" V8_PTR_PREFIX "d, " 12478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "delta: %" V8_PTR_PREFIX "d\n", 12488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang size_of_objects_1, size_of_objects_2, delta); 12493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_GT(size_of_objects_1 / 20, delta); 12508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } else { 12518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang intptr_t delta = size_of_objects_2 - size_of_objects_1; 12528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 12538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "Iterator: %" V8_PTR_PREFIX "d, " 12548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "delta: %" V8_PTR_PREFIX "d\n", 12558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang size_of_objects_1, size_of_objects_2, delta); 12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_GT(size_of_objects_2 / 20, delta); 12578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 12588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 1259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void FillUpNewSpace(NewSpace* new_space) { 12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Fill up new space to the point that it is completely full. Make sure 12633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that the scavenger does not undo the filling. 12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope scope; 12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AlwaysAllocateScope always_allocate; 12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t available = new_space->EffectiveCapacity() - new_space->Size(); 12673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t number_of_fillers = (available / FixedArray::SizeFor(1000)) - 10; 12683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (intptr_t i = 0; i < number_of_fillers; i++) { 12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(1000, NOT_TENURED))); 1270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1272592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 12733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(GrowAndShrinkNewSpace) { 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitializeVM(); 12763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpace* new_space = HEAP->new_space(); 12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Explicitly growing should double the space capacity. 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t old_capacity, new_capacity; 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_capacity = new_space->Capacity(); 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Grow(); 12823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(2 * old_capacity == new_capacity); 12843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_capacity = new_space->Capacity(); 12863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillUpNewSpace(new_space); 12873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(old_capacity == new_capacity); 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Explicitly shrinking should not affect space capacity. 12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_capacity = new_space->Capacity(); 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Shrink(); 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 12943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(old_capacity == new_capacity); 12953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Let the scavenger empty the new space. 12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectGarbage(NEW_SPACE); 12983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_LE(new_space->Size(), old_capacity); 12993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Explicitly shrinking should halve the space capacity. 13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_capacity = new_space->Capacity(); 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Shrink(); 13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(old_capacity == 2 * new_capacity); 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Consecutive shrinking should not affect space capacity. 13073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_capacity = new_space->Capacity(); 13083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Shrink(); 13093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Shrink(); 13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Shrink(); 13113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(old_capacity == new_capacity); 13133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(CollectingAllAvailableGarbageShrinksNewSpace) { 1317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InitializeVM(); 1318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 13193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpace* new_space = HEAP->new_space(); 13203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t old_capacity, new_capacity; 13213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_capacity = new_space->Capacity(); 13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Grow(); 13233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(2 * old_capacity == new_capacity); 13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillUpNewSpace(new_space); 13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_capacity = new_space->Capacity(); 13283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(old_capacity == new_capacity); 13293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic int NumberOfGlobalObjects() { 13333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int count = 0; 13343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapIterator iterator; 13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (obj->IsGlobalObject()) count++; 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return count; 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test that we don't embed maps from foreign contexts into 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// optimized code. 13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(LeakGlobalContextViaMap) { 13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 13463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope outer_scope; 13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx1 = v8::Context::New(); 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx2 = v8::Context::New(); 13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Enter(); 13503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 13523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(4, NumberOfGlobalObjects()); 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 13553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope inner_scope; 13563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var v = {x: 42}"); 13573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); 13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Enter(); 13593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v); 13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> res = CompileRun( 13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f() { return o.x; }" 13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 10; ++i) f();" 13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(f);" 13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f();"); 13653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(42, res->Int32Value()); 13663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); 13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Exit(); 13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Exit(); 13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1.Dispose(); 1370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 13713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(2, NumberOfGlobalObjects()); 13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2.Dispose(); 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, NumberOfGlobalObjects()); 13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test that we don't embed functions from foreign contexts into 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// optimized code. 13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(LeakGlobalContextViaFunction) { 13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope outer_scope; 13843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx1 = v8::Context::New(); 13853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx2 = v8::Context::New(); 13863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Enter(); 13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(4, NumberOfGlobalObjects()); 13903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 13923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope inner_scope; 13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var v = function() { return 42; }"); 13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Enter(); 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v); 13973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> res = CompileRun( 13983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f(x) { return x(); }" 13993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 10; ++i) f(o);" 14003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(f);" 14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(o);"); 14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(42, res->Int32Value()); 14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); 14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Exit(); 14053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Exit(); 14063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1.Dispose(); 1407592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(2, NumberOfGlobalObjects()); 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2.Dispose(); 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, NumberOfGlobalObjects()); 14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(LeakGlobalContextViaMapKeyed) { 14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope outer_scope; 14193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx1 = v8::Context::New(); 14203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx2 = v8::Context::New(); 14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Enter(); 14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(4, NumberOfGlobalObjects()); 14253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1426592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch { 14273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope inner_scope; 14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var v = [42, 43]"); 14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); 14303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Enter(); 14313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v); 14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> res = CompileRun( 14333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f() { return o[0]; }" 14343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 10; ++i) f();" 14353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(f);" 14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f();"); 14373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(42, res->Int32Value()); 14383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); 14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Exit(); 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Exit(); 14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1.Dispose(); 1442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(2, NumberOfGlobalObjects()); 14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2.Dispose(); 14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, NumberOfGlobalObjects()); 14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14513ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(LeakGlobalContextViaMapProto) { 14523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 14533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope outer_scope; 14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx1 = v8::Context::New(); 14553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Context> ctx2 = v8::Context::New(); 14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Enter(); 14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(4, NumberOfGlobalObjects()); 14603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope inner_scope; 14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var v = { y: 42}"); 14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); 14653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Enter(); 14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v); 14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> res = CompileRun( 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f() {" 14693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " var p = {x: 42};" 14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " p.__proto__ = o;" 14713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " return p.x;" 14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}" 14733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 10; ++i) f();" 14743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(f);" 14753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f();"); 14763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(42, res->Int32Value()); 14773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); 14783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2->Exit(); 14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1->Exit(); 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx1.Dispose(); 14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(2, NumberOfGlobalObjects()); 14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ctx2.Dispose(); 14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllAvailableGarbage(); 14863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, NumberOfGlobalObjects()); 14873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14903ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(InstanceOfStubWriteBarrier) { 14913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 14923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 14933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_verify_heap = true; 14943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitializeVM(); 14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!i::V8::UseCrankshaft()) return; 14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope outer_scope; 14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope scope; 15013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function foo () { }" 15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function mkbar () { return new (new Function(\"\")) (); }" 15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f (x) { return (x instanceof foo); }" 15053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function g () { f(mkbar()); }" 15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(new foo()); f(new foo());" 15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(f);" 15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(new foo()); g();"); 15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IncrementalMarking* marking = HEAP->incremental_marking(); 15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking->Abort(); 15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking->Start(); 15143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> f = 15163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Utils::OpenHandle( 15173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *v8::Handle<v8::Function>::Cast( 15183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); 15193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(f->IsOptimized()); 15213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && 15233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !marking->IsStopped()) { 15248f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch // Discard any pending GC requests otherwise we will get GC when we enter 15258f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch // code below. 15268f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); 15273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(marking->IsMarking()); 15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 15323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope scope; 15333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); 15343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Function> g = 15353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); 15363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch g->Call(global, 0, NULL); 15373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->incremental_marking()->set_should_hurry(true); 15403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectGarbage(OLD_POINTER_SPACE); 15413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15443ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(PrototypeTransitionClearing) { 15453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitializeVM(); 15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope scope; 15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 15493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var base = {};" 15503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var live = [];" 15513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 10; i++) {" 15523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " var object = {};" 15533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " var prototype = {};" 15543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " object.__proto__ = prototype;" 15553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " if (i >= 3) live.push(object, prototype);" 15563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}"); 15573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> baseObject = 15593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Utils::OpenHandle( 15603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *v8::Handle<v8::Object>::Cast( 15613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Context::GetCurrent()->Global()->Get(v8_str("base")))); 15623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Verify that only dead prototype transitions are cleared. 15643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions()); 15653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 15663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(10 - 3, baseObject->map()->NumberOfProtoTransitions()); 15673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Verify that prototype transitions array was compacted. 15693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* trans = baseObject->map()->prototype_transitions(); 15703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < 10 - 3; i++) { 15713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int j = Map::kProtoTransitionHeaderSize + 15723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i * Map::kProtoTransitionElementsPerEntry; 15733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap()); 15743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(trans->get(j + Map::kProtoTransitionPrototypeOffset)->IsJSObject()); 15753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Make sure next prototype is placed on an old-space evacuation candidate. 15783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> prototype; 15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PagedSpace* space = HEAP->old_pointer_space(); 15803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch do { 15813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch prototype = FACTORY->NewJSArray(32 * KB, FAST_ELEMENTS, TENURED); 15823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } while (space->FirstPage() == space->LastPage() || 15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !space->LastPage()->Contains(prototype->address())); 15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Add a prototype on an evacuation candidate and verify that transition 15863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // clearing correctly records slots in prototype transition array. 15873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_always_compact = true; 15883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> map(baseObject->map()); 15893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(!space->LastPage()->Contains(map->prototype_transitions()->address())); 15903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(space->LastPage()->Contains(prototype->address())); 15913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch baseObject->SetPrototype(*prototype, false)->ToObjectChecked(); 15923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(map->GetPrototypeTransition(*prototype)->IsMap()); 15933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 15943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(map->GetPrototypeTransition(*prototype)->IsMap()); 1595c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 15968f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 15978f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 15988f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben MurdochTEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { 15998f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch i::FLAG_allow_natives_syntax = true; 16008f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch#ifdef DEBUG 16018f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch i::FLAG_verify_heap = true; 16028f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch#endif 16038f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch InitializeVM(); 16048f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch if (!i::V8::UseCrankshaft()) return; 16058f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::HandleScope outer_scope; 16068f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16078f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch { 16088f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::HandleScope scope; 16098f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CompileRun( 16108f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "function f () {" 16118f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch " var s = 0;" 16128f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch " for (var i = 0; i < 100; i++) s += i;" 16138f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch " return s;" 16148f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "}" 16158f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "f(); f();" 16168f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "%OptimizeFunctionOnNextCall(f);" 16178f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "f();"); 16188f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } 16198f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch Handle<JSFunction> f = 16208f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::Utils::OpenHandle( 16218f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch *v8::Handle<v8::Function>::Cast( 16228f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); 16238f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK(f->IsOptimized()); 16248f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16258f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch IncrementalMarking* marking = HEAP->incremental_marking(); 16268f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch marking->Abort(); 16278f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch marking->Start(); 16288f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16298f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch // The following two calls will increment HEAP->global_ic_age(). 16308f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch const int kLongIdlePauseInMs = 1000; 16318f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::V8::ContextDisposedNotification(); 16328f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::V8::IdleNotification(kLongIdlePauseInMs); 16338f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16348f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch while (!marking->IsStopped() && !marking->IsComplete()) { 16358f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); 16368f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } 16378f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16388f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); 16398f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK_EQ(0, f->shared()->opt_count()); 16408f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK_EQ(0, f->shared()->code()->profiler_ticks()); 16418f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch} 16428f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16438f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16448f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben MurdochTEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { 16458f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch i::FLAG_allow_natives_syntax = true; 16468f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch#ifdef DEBUG 16478f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch i::FLAG_verify_heap = true; 16488f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch#endif 16498f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch InitializeVM(); 16508f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch if (!i::V8::UseCrankshaft()) return; 16518f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::HandleScope outer_scope; 16528f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16538f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch { 16548f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::HandleScope scope; 16558f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CompileRun( 16568f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "function f () {" 16578f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch " var s = 0;" 16588f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch " for (var i = 0; i < 100; i++) s += i;" 16598f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch " return s;" 16608f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "}" 16618f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "f(); f();" 16628f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "%OptimizeFunctionOnNextCall(f);" 16638f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch "f();"); 16648f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } 16658f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch Handle<JSFunction> f = 16668f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::Utils::OpenHandle( 16678f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch *v8::Handle<v8::Function>::Cast( 16688f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); 16698f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK(f->IsOptimized()); 16708f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16718f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch HEAP->incremental_marking()->Abort(); 16728f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16738f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch // The following two calls will increment HEAP->global_ic_age(). 16748f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch // Since incremental marking is off, IdleNotification will do full GC. 16758f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch const int kLongIdlePauseInMs = 1000; 16768f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::V8::ContextDisposedNotification(); 16778f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch v8::V8::IdleNotification(kLongIdlePauseInMs); 16788f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 16798f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); 16808f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK_EQ(0, f->shared()->opt_count()); 16818f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch CHECK_EQ(0, f->shared()->code()->profiler_ticks()); 16828f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch} 1683