OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 | 2 |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "execution.h" | 7 #include "execution.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
10 #include "global-handles.h" | 10 #include "global-handles.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 static void CheckSmi(int value, const char* string) { | 52 static void CheckSmi(int value, const char* string) { |
53 bool exc; | 53 bool exc; |
54 Object* print_string = | 54 Object* print_string = |
55 *Execution::ToString(Handle<Object>(Smi::FromInt(value)), &exc); | 55 *Execution::ToString(Handle<Object>(Smi::FromInt(value)), &exc); |
56 CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); | 56 CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 static void CheckNumber(double value, const char* string) { | 60 static void CheckNumber(double value, const char* string) { |
61 Object* obj = Heap::NumberFromDouble(value); | 61 Object* obj = Heap::NumberFromDouble(value)->ToObjectChecked(); |
62 CHECK(obj->IsNumber()); | 62 CHECK(obj->IsNumber()); |
63 bool exc; | 63 bool exc; |
64 Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc); | 64 Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc); |
65 CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); | 65 CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string))); |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 static void CheckFindCodeObject() { | 69 static void CheckFindCodeObject() { |
70 // Test FindCodeObject | 70 // Test FindCodeObject |
71 #define __ assm. | 71 #define __ assm. |
72 | 72 |
73 Assembler assm(NULL, 0); | 73 Assembler assm(NULL, 0); |
74 | 74 |
75 __ nop(); // supported on all architectures | 75 __ nop(); // supported on all architectures |
76 | 76 |
77 CodeDesc desc; | 77 CodeDesc desc; |
78 assm.GetCode(&desc); | 78 assm.GetCode(&desc); |
79 Object* code = Heap::CreateCode(desc, | 79 Object* code = Heap::CreateCode( |
80 Code::ComputeFlags(Code::STUB), | 80 desc, |
81 Handle<Object>(Heap::undefined_value())); | 81 Code::ComputeFlags(Code::STUB), |
| 82 Handle<Object>(Heap::undefined_value()))->ToObjectChecked(); |
82 CHECK(code->IsCode()); | 83 CHECK(code->IsCode()); |
83 | 84 |
84 HeapObject* obj = HeapObject::cast(code); | 85 HeapObject* obj = HeapObject::cast(code); |
85 Address obj_addr = obj->address(); | 86 Address obj_addr = obj->address(); |
86 | 87 |
87 for (int i = 0; i < obj->Size(); i += kPointerSize) { | 88 for (int i = 0; i < obj->Size(); i += kPointerSize) { |
88 Object* found = Heap::FindCodeObject(obj_addr + i); | 89 Object* found = Heap::FindCodeObject(obj_addr + i); |
89 CHECK_EQ(code, found); | 90 CHECK_EQ(code, found); |
90 } | 91 } |
91 | 92 |
92 Object* copy = Heap::CreateCode(desc, | 93 Object* copy = Heap::CreateCode( |
93 Code::ComputeFlags(Code::STUB), | 94 desc, |
94 Handle<Object>(Heap::undefined_value())); | 95 Code::ComputeFlags(Code::STUB), |
| 96 Handle<Object>(Heap::undefined_value()))->ToObjectChecked(); |
95 CHECK(copy->IsCode()); | 97 CHECK(copy->IsCode()); |
96 HeapObject* obj_copy = HeapObject::cast(copy); | 98 HeapObject* obj_copy = HeapObject::cast(copy); |
97 Object* not_right = Heap::FindCodeObject(obj_copy->address() + | 99 Object* not_right = Heap::FindCodeObject(obj_copy->address() + |
98 obj_copy->Size() / 2); | 100 obj_copy->Size() / 2); |
99 CHECK(not_right != code); | 101 CHECK(not_right != code); |
100 } | 102 } |
101 | 103 |
102 | 104 |
103 TEST(HeapObjects) { | 105 TEST(HeapObjects) { |
104 InitializeVM(); | 106 InitializeVM(); |
105 | 107 |
106 v8::HandleScope sc; | 108 v8::HandleScope sc; |
107 Object* value = Heap::NumberFromDouble(1.000123); | 109 Object* value = Heap::NumberFromDouble(1.000123)->ToObjectChecked(); |
108 CHECK(value->IsHeapNumber()); | 110 CHECK(value->IsHeapNumber()); |
109 CHECK(value->IsNumber()); | 111 CHECK(value->IsNumber()); |
110 CHECK_EQ(1.000123, value->Number()); | 112 CHECK_EQ(1.000123, value->Number()); |
111 | 113 |
112 value = Heap::NumberFromDouble(1.0); | 114 value = Heap::NumberFromDouble(1.0)->ToObjectChecked(); |
113 CHECK(value->IsSmi()); | 115 CHECK(value->IsSmi()); |
114 CHECK(value->IsNumber()); | 116 CHECK(value->IsNumber()); |
115 CHECK_EQ(1.0, value->Number()); | 117 CHECK_EQ(1.0, value->Number()); |
116 | 118 |
117 value = Heap::NumberFromInt32(1024); | 119 value = Heap::NumberFromInt32(1024)->ToObjectChecked(); |
118 CHECK(value->IsSmi()); | 120 CHECK(value->IsSmi()); |
119 CHECK(value->IsNumber()); | 121 CHECK(value->IsNumber()); |
120 CHECK_EQ(1024.0, value->Number()); | 122 CHECK_EQ(1024.0, value->Number()); |
121 | 123 |
122 value = Heap::NumberFromInt32(Smi::kMinValue); | 124 value = Heap::NumberFromInt32(Smi::kMinValue)->ToObjectChecked(); |
123 CHECK(value->IsSmi()); | 125 CHECK(value->IsSmi()); |
124 CHECK(value->IsNumber()); | 126 CHECK(value->IsNumber()); |
125 CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value()); | 127 CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value()); |
126 | 128 |
127 value = Heap::NumberFromInt32(Smi::kMaxValue); | 129 value = Heap::NumberFromInt32(Smi::kMaxValue)->ToObjectChecked(); |
128 CHECK(value->IsSmi()); | 130 CHECK(value->IsSmi()); |
129 CHECK(value->IsNumber()); | 131 CHECK(value->IsNumber()); |
130 CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value()); | 132 CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value()); |
131 | 133 |
132 #ifndef V8_TARGET_ARCH_X64 | 134 #ifndef V8_TARGET_ARCH_X64 |
133 // TODO(lrn): We need a NumberFromIntptr function in order to test this. | 135 // TODO(lrn): We need a NumberFromIntptr function in order to test this. |
134 value = Heap::NumberFromInt32(Smi::kMinValue - 1); | 136 value = Heap::NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked(); |
135 CHECK(value->IsHeapNumber()); | 137 CHECK(value->IsHeapNumber()); |
136 CHECK(value->IsNumber()); | 138 CHECK(value->IsNumber()); |
137 CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number()); | 139 CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number()); |
138 #endif | 140 #endif |
139 | 141 |
140 value = Heap::NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); | 142 MaybeObject* maybe_value = |
| 143 Heap::NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); |
| 144 value = maybe_value->ToObjectChecked(); |
141 CHECK(value->IsHeapNumber()); | 145 CHECK(value->IsHeapNumber()); |
142 CHECK(value->IsNumber()); | 146 CHECK(value->IsNumber()); |
143 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), | 147 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), |
144 value->Number()); | 148 value->Number()); |
145 | 149 |
146 // nan oddball checks | 150 // nan oddball checks |
147 CHECK(Heap::nan_value()->IsNumber()); | 151 CHECK(Heap::nan_value()->IsNumber()); |
148 CHECK(isnan(Heap::nan_value()->Number())); | 152 CHECK(isnan(Heap::nan_value()->Number())); |
149 | 153 |
150 Handle<String> s = Factory::NewStringFromAscii(CStrVector("fisk hest ")); | 154 Handle<String> s = Factory::NewStringFromAscii(CStrVector("fisk hest ")); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); | 205 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); |
202 | 206 |
203 { | 207 { |
204 v8::HandleScope inner_scope; | 208 v8::HandleScope inner_scope; |
205 // Allocate a function and keep it in global object's property. | 209 // Allocate a function and keep it in global object's property. |
206 Handle<JSFunction> function = | 210 Handle<JSFunction> function = |
207 Factory::NewFunction(name, Factory::undefined_value()); | 211 Factory::NewFunction(name, Factory::undefined_value()); |
208 Handle<Map> initial_map = | 212 Handle<Map> initial_map = |
209 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 213 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
210 function->set_initial_map(*initial_map); | 214 function->set_initial_map(*initial_map); |
211 Top::context()->global()->SetProperty(*name, *function, NONE); | 215 Top::context()->global()->SetProperty(*name, |
| 216 *function, |
| 217 NONE)->ToObjectChecked(); |
212 // Allocate an object. Unrooted after leaving the scope. | 218 // Allocate an object. Unrooted after leaving the scope. |
213 Handle<JSObject> obj = Factory::NewJSObject(function); | 219 Handle<JSObject> obj = Factory::NewJSObject(function); |
214 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 220 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE)->ToObjectChecked(); |
215 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE); | 221 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE)->ToObjectChecked(); |
216 | 222 |
217 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 223 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
218 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); | 224 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); |
219 } | 225 } |
220 | 226 |
221 Heap::CollectGarbage(NEW_SPACE); | 227 Heap::CollectGarbage(NEW_SPACE); |
222 | 228 |
223 // Function should be alive. | 229 // Function should be alive. |
224 CHECK(Top::context()->global()->HasLocalProperty(*name)); | 230 CHECK(Top::context()->global()->HasLocalProperty(*name)); |
225 // Check function is retained. | 231 // Check function is retained. |
226 Object* func_value = Top::context()->global()->GetProperty(*name); | 232 Object* func_value = |
| 233 Top::context()->global()->GetProperty(*name)->ToObjectChecked(); |
227 CHECK(func_value->IsJSFunction()); | 234 CHECK(func_value->IsJSFunction()); |
228 Handle<JSFunction> function(JSFunction::cast(func_value)); | 235 Handle<JSFunction> function(JSFunction::cast(func_value)); |
229 | 236 |
230 { | 237 { |
231 HandleScope inner_scope; | 238 HandleScope inner_scope; |
232 // Allocate another object, make it reachable from global. | 239 // Allocate another object, make it reachable from global. |
233 Handle<JSObject> obj = Factory::NewJSObject(function); | 240 Handle<JSObject> obj = Factory::NewJSObject(function); |
234 Top::context()->global()->SetProperty(*obj_name, *obj, NONE); | 241 Top::context()->global()->SetProperty(*obj_name, |
235 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 242 *obj, |
| 243 NONE)->ToObjectChecked(); |
| 244 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE)->ToObjectChecked(); |
236 } | 245 } |
237 | 246 |
238 // After gc, it should survive. | 247 // After gc, it should survive. |
239 Heap::CollectGarbage(NEW_SPACE); | 248 Heap::CollectGarbage(NEW_SPACE); |
240 | 249 |
241 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); | 250 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); |
242 CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject()); | 251 CHECK(Top::context()->global()->GetProperty(*obj_name)->ToObjectChecked()-> |
243 JSObject* obj = | 252 IsJSObject()); |
244 JSObject::cast(Top::context()->global()->GetProperty(*obj_name)); | 253 Object* obj = |
245 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 254 Top::context()->global()->GetProperty(*obj_name)->ToObjectChecked(); |
| 255 JSObject* js_obj = JSObject::cast(obj); |
| 256 CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name)); |
246 } | 257 } |
247 | 258 |
248 | 259 |
249 static void VerifyStringAllocation(const char* string) { | 260 static void VerifyStringAllocation(const char* string) { |
250 v8::HandleScope scope; | 261 v8::HandleScope scope; |
251 Handle<String> s = Factory::NewStringFromUtf8(CStrVector(string)); | 262 Handle<String> s = Factory::NewStringFromUtf8(CStrVector(string)); |
252 CHECK_EQ(StrLength(string), s->length()); | 263 CHECK_EQ(StrLength(string), s->length()); |
253 for (int index = 0; index < s->length(); index++) { | 264 for (int index = 0; index < s->length(); index++) { |
254 CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index)); | 265 CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index)); |
255 } | 266 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 "void", | 498 "void", |
488 "volatile", | 499 "volatile", |
489 "while", | 500 "while", |
490 "with", | 501 "with", |
491 0 | 502 0 |
492 }; | 503 }; |
493 | 504 |
494 | 505 |
495 static void CheckSymbols(const char** strings) { | 506 static void CheckSymbols(const char** strings) { |
496 for (const char* string = *strings; *strings != 0; string = *strings++) { | 507 for (const char* string = *strings; *strings != 0; string = *strings++) { |
497 Object* a = Heap::LookupAsciiSymbol(string); | 508 Object* a; |
| 509 MaybeObject* maybe_a = Heap::LookupAsciiSymbol(string); |
498 // LookupAsciiSymbol may return a failure if a GC is needed. | 510 // LookupAsciiSymbol may return a failure if a GC is needed. |
499 if (a->IsFailure()) continue; | 511 if (!maybe_a->ToObject(&a)) continue; |
500 CHECK(a->IsSymbol()); | 512 CHECK(a->IsSymbol()); |
501 Object* b = Heap::LookupAsciiSymbol(string); | 513 Object* b; |
502 if (b->IsFailure()) continue; | 514 MaybeObject* maybe_b = Heap::LookupAsciiSymbol(string); |
| 515 if (!maybe_maybe_b->ToObject(&b)) continue; |
503 CHECK_EQ(b, a); | 516 CHECK_EQ(b, a); |
504 CHECK(String::cast(b)->IsEqualTo(CStrVector(string))); | 517 CHECK(String::cast(b)->IsEqualTo(CStrVector(string))); |
505 } | 518 } |
506 } | 519 } |
507 | 520 |
508 | 521 |
509 TEST(SymbolTable) { | 522 TEST(SymbolTable) { |
510 InitializeVM(); | 523 InitializeVM(); |
511 | 524 |
512 CheckSymbols(not_so_random_string_table); | 525 CheckSymbols(not_so_random_string_table); |
513 CheckSymbols(not_so_random_string_table); | 526 CheckSymbols(not_so_random_string_table); |
514 } | 527 } |
515 | 528 |
516 | 529 |
517 TEST(FunctionAllocation) { | 530 TEST(FunctionAllocation) { |
518 InitializeVM(); | 531 InitializeVM(); |
519 | 532 |
520 v8::HandleScope sc; | 533 v8::HandleScope sc; |
521 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); | 534 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
522 Handle<JSFunction> function = | 535 Handle<JSFunction> function = |
523 Factory::NewFunction(name, Factory::undefined_value()); | 536 Factory::NewFunction(name, Factory::undefined_value()); |
524 Handle<Map> initial_map = | 537 Handle<Map> initial_map = |
525 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 538 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
526 function->set_initial_map(*initial_map); | 539 function->set_initial_map(*initial_map); |
527 | 540 |
528 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); | 541 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
529 Handle<JSObject> obj = Factory::NewJSObject(function); | 542 Handle<JSObject> obj = Factory::NewJSObject(function); |
530 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 543 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE)->ToObjectChecked(); |
531 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 544 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
532 // Check that we can add properties to function objects. | 545 // Check that we can add properties to function objects. |
533 function->SetProperty(*prop_name, Smi::FromInt(24), NONE); | 546 function->SetProperty(*prop_name, |
| 547 Smi::FromInt(24), |
| 548 NONE)->ToObjectChecked(); |
534 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); | 549 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); |
535 } | 550 } |
536 | 551 |
537 | 552 |
538 TEST(ObjectProperties) { | 553 TEST(ObjectProperties) { |
539 InitializeVM(); | 554 InitializeVM(); |
540 | 555 |
541 v8::HandleScope sc; | 556 v8::HandleScope sc; |
542 String* object_symbol = String::cast(Heap::Object_symbol()); | 557 String* object_symbol = String::cast(Heap::Object_symbol()); |
543 JSFunction* object_function = | 558 Object* raw_object = |
544 JSFunction::cast(Top::context()->global()->GetProperty(object_symbol)); | 559 Top::context()->global()->GetProperty(object_symbol)->ToObjectChecked(); |
| 560 JSFunction* object_function = JSFunction::cast(raw_object); |
545 Handle<JSFunction> constructor(object_function); | 561 Handle<JSFunction> constructor(object_function); |
546 Handle<JSObject> obj = Factory::NewJSObject(constructor); | 562 Handle<JSObject> obj = Factory::NewJSObject(constructor); |
547 Handle<String> first = Factory::LookupAsciiSymbol("first"); | 563 Handle<String> first = Factory::LookupAsciiSymbol("first"); |
548 Handle<String> second = Factory::LookupAsciiSymbol("second"); | 564 Handle<String> second = Factory::LookupAsciiSymbol("second"); |
549 | 565 |
550 // check for empty | 566 // check for empty |
551 CHECK(!obj->HasLocalProperty(*first)); | 567 CHECK(!obj->HasLocalProperty(*first)); |
552 | 568 |
553 // add first | 569 // add first |
554 obj->SetProperty(*first, Smi::FromInt(1), NONE); | 570 obj->SetProperty(*first, Smi::FromInt(1), NONE)->ToObjectChecked(); |
555 CHECK(obj->HasLocalProperty(*first)); | 571 CHECK(obj->HasLocalProperty(*first)); |
556 | 572 |
557 // delete first | 573 // delete first |
558 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); | 574 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); |
559 CHECK(!obj->HasLocalProperty(*first)); | 575 CHECK(!obj->HasLocalProperty(*first)); |
560 | 576 |
561 // add first and then second | 577 // add first and then second |
562 obj->SetProperty(*first, Smi::FromInt(1), NONE); | 578 obj->SetProperty(*first, Smi::FromInt(1), NONE)->ToObjectChecked(); |
563 obj->SetProperty(*second, Smi::FromInt(2), NONE); | 579 obj->SetProperty(*second, Smi::FromInt(2), NONE)->ToObjectChecked(); |
564 CHECK(obj->HasLocalProperty(*first)); | 580 CHECK(obj->HasLocalProperty(*first)); |
565 CHECK(obj->HasLocalProperty(*second)); | 581 CHECK(obj->HasLocalProperty(*second)); |
566 | 582 |
567 // delete first and then second | 583 // delete first and then second |
568 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); | 584 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); |
569 CHECK(obj->HasLocalProperty(*second)); | 585 CHECK(obj->HasLocalProperty(*second)); |
570 CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); | 586 CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); |
571 CHECK(!obj->HasLocalProperty(*first)); | 587 CHECK(!obj->HasLocalProperty(*first)); |
572 CHECK(!obj->HasLocalProperty(*second)); | 588 CHECK(!obj->HasLocalProperty(*second)); |
573 | 589 |
574 // add first and then second | 590 // add first and then second |
575 obj->SetProperty(*first, Smi::FromInt(1), NONE); | 591 obj->SetProperty(*first, Smi::FromInt(1), NONE)->ToObjectChecked(); |
576 obj->SetProperty(*second, Smi::FromInt(2), NONE); | 592 obj->SetProperty(*second, Smi::FromInt(2), NONE)->ToObjectChecked(); |
577 CHECK(obj->HasLocalProperty(*first)); | 593 CHECK(obj->HasLocalProperty(*first)); |
578 CHECK(obj->HasLocalProperty(*second)); | 594 CHECK(obj->HasLocalProperty(*second)); |
579 | 595 |
580 // delete second and then first | 596 // delete second and then first |
581 CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); | 597 CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); |
582 CHECK(obj->HasLocalProperty(*first)); | 598 CHECK(obj->HasLocalProperty(*first)); |
583 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); | 599 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); |
584 CHECK(!obj->HasLocalProperty(*first)); | 600 CHECK(!obj->HasLocalProperty(*first)); |
585 CHECK(!obj->HasLocalProperty(*second)); | 601 CHECK(!obj->HasLocalProperty(*second)); |
586 | 602 |
587 // check string and symbol match | 603 // check string and symbol match |
588 static const char* string1 = "fisk"; | 604 static const char* string1 = "fisk"; |
589 Handle<String> s1 = Factory::NewStringFromAscii(CStrVector(string1)); | 605 Handle<String> s1 = Factory::NewStringFromAscii(CStrVector(string1)); |
590 obj->SetProperty(*s1, Smi::FromInt(1), NONE); | 606 obj->SetProperty(*s1, Smi::FromInt(1), NONE)->ToObjectChecked(); |
591 Handle<String> s1_symbol = Factory::LookupAsciiSymbol(string1); | 607 Handle<String> s1_symbol = Factory::LookupAsciiSymbol(string1); |
592 CHECK(obj->HasLocalProperty(*s1_symbol)); | 608 CHECK(obj->HasLocalProperty(*s1_symbol)); |
593 | 609 |
594 // check symbol and string match | 610 // check symbol and string match |
595 static const char* string2 = "fugl"; | 611 static const char* string2 = "fugl"; |
596 Handle<String> s2_symbol = Factory::LookupAsciiSymbol(string2); | 612 Handle<String> s2_symbol = Factory::LookupAsciiSymbol(string2); |
597 obj->SetProperty(*s2_symbol, Smi::FromInt(1), NONE); | 613 obj->SetProperty(*s2_symbol, Smi::FromInt(1), NONE)->ToObjectChecked(); |
598 Handle<String> s2 = Factory::NewStringFromAscii(CStrVector(string2)); | 614 Handle<String> s2 = Factory::NewStringFromAscii(CStrVector(string2)); |
599 CHECK(obj->HasLocalProperty(*s2)); | 615 CHECK(obj->HasLocalProperty(*s2)); |
600 } | 616 } |
601 | 617 |
602 | 618 |
603 TEST(JSObjectMaps) { | 619 TEST(JSObjectMaps) { |
604 InitializeVM(); | 620 InitializeVM(); |
605 | 621 |
606 v8::HandleScope sc; | 622 v8::HandleScope sc; |
607 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); | 623 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
608 Handle<JSFunction> function = | 624 Handle<JSFunction> function = |
609 Factory::NewFunction(name, Factory::undefined_value()); | 625 Factory::NewFunction(name, Factory::undefined_value()); |
610 Handle<Map> initial_map = | 626 Handle<Map> initial_map = |
611 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 627 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
612 function->set_initial_map(*initial_map); | 628 function->set_initial_map(*initial_map); |
613 | 629 |
614 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); | 630 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
615 Handle<JSObject> obj = Factory::NewJSObject(function); | 631 Handle<JSObject> obj = Factory::NewJSObject(function); |
616 | 632 |
617 // Set a propery | 633 // Set a propery |
618 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 634 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE)->ToObjectChecked(); |
619 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 635 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
620 | 636 |
621 // Check the map has changed | 637 // Check the map has changed |
622 CHECK(*initial_map != obj->map()); | 638 CHECK(*initial_map != obj->map()); |
623 } | 639 } |
624 | 640 |
625 | 641 |
626 TEST(JSArray) { | 642 TEST(JSArray) { |
627 InitializeVM(); | 643 InitializeVM(); |
628 | 644 |
629 v8::HandleScope sc; | 645 v8::HandleScope sc; |
630 Handle<String> name = Factory::LookupAsciiSymbol("Array"); | 646 Handle<String> name = Factory::LookupAsciiSymbol("Array"); |
| 647 Object* raw_object = |
| 648 Top::context()->global()->GetProperty(*name)->ToObjectChecked(); |
631 Handle<JSFunction> function = Handle<JSFunction>( | 649 Handle<JSFunction> function = Handle<JSFunction>( |
632 JSFunction::cast(Top::context()->global()->GetProperty(*name))); | 650 JSFunction::cast(raw_object)); |
633 | 651 |
634 // Allocate the object. | 652 // Allocate the object. |
635 Handle<JSObject> object = Factory::NewJSObject(function); | 653 Handle<JSObject> object = Factory::NewJSObject(function); |
636 Handle<JSArray> array = Handle<JSArray>::cast(object); | 654 Handle<JSArray> array = Handle<JSArray>::cast(object); |
637 Object* ok = array->Initialize(0); | |
638 // We just initialized the VM, no heap allocation failure yet. | 655 // We just initialized the VM, no heap allocation failure yet. |
639 CHECK(!ok->IsFailure()); | 656 Object* ok = array->Initialize(0)->ToObjectChecked(); |
640 | 657 |
641 // Set array length to 0. | 658 // Set array length to 0. |
642 ok = array->SetElementsLength(Smi::FromInt(0)); | 659 ok = array->SetElementsLength(Smi::FromInt(0))->ToObjectChecked(); |
643 CHECK(!ok->IsFailure()); | |
644 CHECK_EQ(Smi::FromInt(0), array->length()); | 660 CHECK_EQ(Smi::FromInt(0), array->length()); |
645 CHECK(array->HasFastElements()); // Must be in fast mode. | 661 CHECK(array->HasFastElements()); // Must be in fast mode. |
646 | 662 |
647 // array[length] = name. | 663 // array[length] = name. |
648 ok = array->SetElement(0, *name); | 664 ok = array->SetElement(0, *name)->ToObjectChecked(); |
649 CHECK(!ok->IsFailure()); | |
650 CHECK_EQ(Smi::FromInt(1), array->length()); | 665 CHECK_EQ(Smi::FromInt(1), array->length()); |
651 CHECK_EQ(array->GetElement(0), *name); | 666 CHECK_EQ(array->GetElement(0), *name); |
652 | 667 |
653 // Set array length with larger than smi value. | 668 // Set array length with larger than smi value. |
654 Handle<Object> length = | 669 Handle<Object> length = |
655 Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1); | 670 Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1); |
656 ok = array->SetElementsLength(*length); | 671 ok = array->SetElementsLength(*length)->ToObjectChecked(); |
657 CHECK(!ok->IsFailure()); | |
658 | 672 |
659 uint32_t int_length = 0; | 673 uint32_t int_length = 0; |
660 CHECK(length->ToArrayIndex(&int_length)); | 674 CHECK(length->ToArrayIndex(&int_length)); |
661 CHECK_EQ(*length, array->length()); | 675 CHECK_EQ(*length, array->length()); |
662 CHECK(array->HasDictionaryElements()); // Must be in slow mode. | 676 CHECK(array->HasDictionaryElements()); // Must be in slow mode. |
663 | 677 |
664 // array[length] = name. | 678 // array[length] = name. |
665 ok = array->SetElement(int_length, *name); | 679 ok = array->SetElement(int_length, *name)->ToObjectChecked(); |
666 CHECK(!ok->IsFailure()); | |
667 uint32_t new_int_length = 0; | 680 uint32_t new_int_length = 0; |
668 CHECK(array->length()->ToArrayIndex(&new_int_length)); | 681 CHECK(array->length()->ToArrayIndex(&new_int_length)); |
669 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); | 682 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); |
670 CHECK_EQ(array->GetElement(int_length), *name); | 683 CHECK_EQ(array->GetElement(int_length), *name); |
671 CHECK_EQ(array->GetElement(0), *name); | 684 CHECK_EQ(array->GetElement(0), *name); |
672 } | 685 } |
673 | 686 |
674 | 687 |
675 TEST(JSObjectCopy) { | 688 TEST(JSObjectCopy) { |
676 InitializeVM(); | 689 InitializeVM(); |
677 | 690 |
678 v8::HandleScope sc; | 691 v8::HandleScope sc; |
679 String* object_symbol = String::cast(Heap::Object_symbol()); | 692 String* object_symbol = String::cast(Heap::Object_symbol()); |
680 JSFunction* object_function = | 693 Object* raw_object = |
681 JSFunction::cast(Top::context()->global()->GetProperty(object_symbol)); | 694 Top::context()->global()->GetProperty(object_symbol)->ToObjectChecked(); |
| 695 JSFunction* object_function = JSFunction::cast(raw_object); |
682 Handle<JSFunction> constructor(object_function); | 696 Handle<JSFunction> constructor(object_function); |
683 Handle<JSObject> obj = Factory::NewJSObject(constructor); | 697 Handle<JSObject> obj = Factory::NewJSObject(constructor); |
684 Handle<String> first = Factory::LookupAsciiSymbol("first"); | 698 Handle<String> first = Factory::LookupAsciiSymbol("first"); |
685 Handle<String> second = Factory::LookupAsciiSymbol("second"); | 699 Handle<String> second = Factory::LookupAsciiSymbol("second"); |
686 | 700 |
687 obj->SetProperty(*first, Smi::FromInt(1), NONE); | 701 obj->SetProperty(*first, Smi::FromInt(1), NONE)->ToObjectChecked(); |
688 obj->SetProperty(*second, Smi::FromInt(2), NONE); | 702 obj->SetProperty(*second, Smi::FromInt(2), NONE)->ToObjectChecked(); |
689 | 703 |
690 Object* ok = obj->SetElement(0, *first); | 704 Object* ok = obj->SetElement(0, *first)->ToObjectChecked(); |
691 CHECK(!ok->IsFailure()); | |
692 | 705 |
693 ok = obj->SetElement(1, *second); | 706 ok = obj->SetElement(1, *second)->ToObjectChecked(); |
694 CHECK(!ok->IsFailure()); | |
695 | 707 |
696 // Make the clone. | 708 // Make the clone. |
697 Handle<JSObject> clone = Copy(obj); | 709 Handle<JSObject> clone = Copy(obj); |
698 CHECK(!clone.is_identical_to(obj)); | 710 CHECK(!clone.is_identical_to(obj)); |
699 | 711 |
700 CHECK_EQ(obj->GetElement(0), clone->GetElement(0)); | 712 CHECK_EQ(obj->GetElement(0), clone->GetElement(0)); |
701 CHECK_EQ(obj->GetElement(1), clone->GetElement(1)); | 713 CHECK_EQ(obj->GetElement(1), clone->GetElement(1)); |
702 | 714 |
703 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first)); | 715 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first)); |
704 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); | 716 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); |
705 | 717 |
706 // Flip the values. | 718 // Flip the values. |
707 clone->SetProperty(*first, Smi::FromInt(2), NONE); | 719 clone->SetProperty(*first, Smi::FromInt(2), NONE)->ToObjectChecked(); |
708 clone->SetProperty(*second, Smi::FromInt(1), NONE); | 720 clone->SetProperty(*second, Smi::FromInt(1), NONE)->ToObjectChecked(); |
709 | 721 |
710 ok = clone->SetElement(0, *second); | 722 ok = clone->SetElement(0, *second)->ToObjectChecked(); |
711 CHECK(!ok->IsFailure()); | 723 ok = clone->SetElement(1, *first)->ToObjectChecked(); |
712 ok = clone->SetElement(1, *first); | |
713 CHECK(!ok->IsFailure()); | |
714 | 724 |
715 CHECK_EQ(obj->GetElement(1), clone->GetElement(0)); | 725 CHECK_EQ(obj->GetElement(1), clone->GetElement(0)); |
716 CHECK_EQ(obj->GetElement(0), clone->GetElement(1)); | 726 CHECK_EQ(obj->GetElement(0), clone->GetElement(1)); |
717 | 727 |
718 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first)); | 728 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first)); |
719 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second)); | 729 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second)); |
720 } | 730 } |
721 | 731 |
722 | 732 |
723 TEST(StringAllocation) { | 733 TEST(StringAllocation) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 intptr_t* flags_ptr = &Page::FromAddress(next_page)->flags_; | 839 intptr_t* flags_ptr = &Page::FromAddress(next_page)->flags_; |
830 Address flags_addr = reinterpret_cast<Address>(flags_ptr); | 840 Address flags_addr = reinterpret_cast<Address>(flags_ptr); |
831 | 841 |
832 int bytes_to_allocate = | 842 int bytes_to_allocate = |
833 static_cast<int>(flags_addr - current_top) + kPointerSize; | 843 static_cast<int>(flags_addr - current_top) + kPointerSize; |
834 | 844 |
835 int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) / | 845 int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) / |
836 kPointerSize; | 846 kPointerSize; |
837 CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements)); | 847 CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements)); |
838 FixedArray* array = FixedArray::cast( | 848 FixedArray* array = FixedArray::cast( |
839 Heap::AllocateFixedArray(n_elements)); | 849 Heap::AllocateFixedArray(n_elements)->ToObjectChecked()); |
840 | 850 |
841 int index = n_elements - 1; | 851 int index = n_elements - 1; |
842 CHECK_EQ(flags_ptr, | 852 CHECK_EQ(flags_ptr, |
843 HeapObject::RawField(array, FixedArray::OffsetOfElementAt(index))); | 853 HeapObject::RawField(array, FixedArray::OffsetOfElementAt(index))); |
844 array->set(index, Smi::FromInt(0)); | 854 array->set(index, Smi::FromInt(0)); |
845 // This chould have turned next page into LargeObjectPage: | 855 // This chould have turned next page into LargeObjectPage: |
846 // CHECK(Page::FromAddress(next_page)->IsLargeObjectPage()); | 856 // CHECK(Page::FromAddress(next_page)->IsLargeObjectPage()); |
847 | 857 |
848 HeapObject* addr = HeapObject::FromAddress(next_page + 2 * kPointerSize); | 858 HeapObject* addr = HeapObject::FromAddress(next_page + 2 * kPointerSize); |
849 CHECK(Heap::new_space()->Contains(addr)); | 859 CHECK(Heap::new_space()->Contains(addr)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 // just enough room to allocate JSObject and thus fill the newspace. | 911 // just enough room to allocate JSObject and thus fill the newspace. |
902 | 912 |
903 int allocation_amount = Min(FixedArray::kMaxSize, | 913 int allocation_amount = Min(FixedArray::kMaxSize, |
904 Heap::MaxObjectSizeInNewSpace()); | 914 Heap::MaxObjectSizeInNewSpace()); |
905 int allocation_len = LenFromSize(allocation_amount); | 915 int allocation_len = LenFromSize(allocation_amount); |
906 NewSpace* new_space = Heap::new_space(); | 916 NewSpace* new_space = Heap::new_space(); |
907 Address* top_addr = new_space->allocation_top_address(); | 917 Address* top_addr = new_space->allocation_top_address(); |
908 Address* limit_addr = new_space->allocation_limit_address(); | 918 Address* limit_addr = new_space->allocation_limit_address(); |
909 while ((*limit_addr - *top_addr) > allocation_amount) { | 919 while ((*limit_addr - *top_addr) > allocation_amount) { |
910 CHECK(!Heap::always_allocate()); | 920 CHECK(!Heap::always_allocate()); |
911 Object* array = Heap::AllocateFixedArray(allocation_len); | 921 Object* array = |
912 CHECK(!array->IsFailure()); | 922 Heap::AllocateFixedArray(allocation_len)->ToObjectChecked(); |
913 CHECK(new_space->Contains(array)); | 923 CHECK(new_space->Contains(array)); |
914 } | 924 } |
915 | 925 |
916 // Step 3: now allocate fixed array and JSObject to fill the whole new space. | 926 // Step 3: now allocate fixed array and JSObject to fill the whole new space. |
917 int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size); | 927 int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size); |
918 int fixed_array_len = LenFromSize(to_fill); | 928 int fixed_array_len = LenFromSize(to_fill); |
919 CHECK(fixed_array_len < FixedArray::kMaxLength); | 929 CHECK(fixed_array_len < FixedArray::kMaxLength); |
920 | 930 |
921 CHECK(!Heap::always_allocate()); | 931 CHECK(!Heap::always_allocate()); |
922 Object* array = Heap::AllocateFixedArray(fixed_array_len); | 932 Object* array = |
923 CHECK(!array->IsFailure()); | 933 Heap::AllocateFixedArray(fixed_array_len)->ToObjectChecked(); |
924 CHECK(new_space->Contains(array)); | 934 CHECK(new_space->Contains(array)); |
925 | 935 |
926 Object* object = Heap::AllocateJSObjectFromMap(*my_map); | 936 Object* object = Heap::AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); |
927 CHECK(!object->IsFailure()); | |
928 CHECK(new_space->Contains(object)); | 937 CHECK(new_space->Contains(object)); |
929 JSObject* jsobject = JSObject::cast(object); | 938 JSObject* jsobject = JSObject::cast(object); |
930 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); | 939 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); |
931 CHECK_EQ(0, jsobject->properties()->length()); | 940 CHECK_EQ(0, jsobject->properties()->length()); |
932 // Create a reference to object in new space in jsobject. | 941 // Create a reference to object in new space in jsobject. |
933 jsobject->FastPropertyAtPut(-1, array); | 942 jsobject->FastPropertyAtPut(-1, array); |
934 | 943 |
935 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); | 944 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); |
936 | 945 |
937 // Step 4: clone jsobject, but force always allocate first to create a clone | 946 // Step 4: clone jsobject, but force always allocate first to create a clone |
938 // in old pointer space. | 947 // in old pointer space. |
939 Address old_pointer_space_top = Heap::old_pointer_space()->top(); | 948 Address old_pointer_space_top = Heap::old_pointer_space()->top(); |
940 AlwaysAllocateScope aa_scope; | 949 AlwaysAllocateScope aa_scope; |
941 Object* clone_obj = Heap::CopyJSObject(jsobject); | 950 Object* clone_obj = Heap::CopyJSObject(jsobject)->ToObjectChecked(); |
942 CHECK(!object->IsFailure()); | |
943 JSObject* clone = JSObject::cast(clone_obj); | 951 JSObject* clone = JSObject::cast(clone_obj); |
944 if (clone->address() != old_pointer_space_top) { | 952 if (clone->address() != old_pointer_space_top) { |
945 // Alas, got allocated from free list, we cannot do checks. | 953 // Alas, got allocated from free list, we cannot do checks. |
946 return; | 954 return; |
947 } | 955 } |
948 CHECK(Heap::old_pointer_space()->Contains(clone->address())); | 956 CHECK(Heap::old_pointer_space()->Contains(clone->address())); |
949 | 957 |
950 // Step 5: verify validity of region dirty marks. | 958 // Step 5: verify validity of region dirty marks. |
951 Address clone_addr = clone->address(); | 959 Address clone_addr = clone->address(); |
952 Page* page = Page::FromAddress(clone_addr); | 960 Page* page = Page::FromAddress(clone_addr); |
(...skipping 13 matching lines...) Expand all Loading... |
966 " var y = 42;" | 974 " var y = 42;" |
967 " var z = x + y;" | 975 " var z = x + y;" |
968 "};" | 976 "};" |
969 "foo()"; | 977 "foo()"; |
970 Handle<String> foo_name = Factory::LookupAsciiSymbol("foo"); | 978 Handle<String> foo_name = Factory::LookupAsciiSymbol("foo"); |
971 | 979 |
972 // This compile will add the code to the compilation cache. | 980 // This compile will add the code to the compilation cache. |
973 CompileRun(source); | 981 CompileRun(source); |
974 | 982 |
975 // Check function is compiled. | 983 // Check function is compiled. |
976 Object* func_value = Top::context()->global()->GetProperty(*foo_name); | 984 Object* func_value = |
| 985 Top::context()->global()->GetProperty(*foo_name)->ToObjectChecked(); |
977 CHECK(func_value->IsJSFunction()); | 986 CHECK(func_value->IsJSFunction()); |
978 Handle<JSFunction> function(JSFunction::cast(func_value)); | 987 Handle<JSFunction> function(JSFunction::cast(func_value)); |
979 CHECK(function->shared()->is_compiled()); | 988 CHECK(function->shared()->is_compiled()); |
980 | 989 |
981 Heap::CollectAllGarbage(true); | 990 Heap::CollectAllGarbage(true); |
982 Heap::CollectAllGarbage(true); | 991 Heap::CollectAllGarbage(true); |
983 | 992 |
984 CHECK(function->shared()->is_compiled()); | 993 CHECK(function->shared()->is_compiled()); |
985 | 994 |
986 Heap::CollectAllGarbage(true); | 995 Heap::CollectAllGarbage(true); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 // with and without GCs while iterating the list. | 1088 // with and without GCs while iterating the list. |
1080 for (int i = 0; i < kNumTestContexts; i++) { | 1089 for (int i = 0; i < kNumTestContexts; i++) { |
1081 ctx[i] = v8::Context::New(); | 1090 ctx[i] = v8::Context::New(); |
1082 CHECK_EQ(i + 1, CountGlobalContexts()); | 1091 CHECK_EQ(i + 1, CountGlobalContexts()); |
1083 CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); | 1092 CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); |
1084 | 1093 |
1085 ctx[i]->Enter(); | 1094 ctx[i]->Enter(); |
1086 ctx[i]->Exit(); | 1095 ctx[i]->Exit(); |
1087 } | 1096 } |
1088 } | 1097 } |
OLD | NEW |