Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/objects.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "vm-state-inl.h" 48 #include "vm-state-inl.h"
49 49
50 #ifdef ENABLE_DISASSEMBLER 50 #ifdef ENABLE_DISASSEMBLER
51 #include "disasm.h" 51 #include "disasm.h"
52 #include "disassembler.h" 52 #include "disassembler.h"
53 #endif 53 #endif
54 54
55 namespace v8 { 55 namespace v8 {
56 namespace internal { 56 namespace internal {
57 57
58 void PrintElementsKind(FILE* out, ElementsKind kind) {
59 switch (kind) {
60 case FAST_SMI_ONLY_ELEMENTS:
61 PrintF(out, "FAST_SMI_ONLY_ELEMENTS");
62 break;
63 case FAST_ELEMENTS:
64 PrintF(out, "FAST_ELEMENTS");
65 break;
66 case FAST_DOUBLE_ELEMENTS:
67 PrintF(out, "FAST_DOUBLE_ELEMENTS");
68 break;
69 case DICTIONARY_ELEMENTS:
70 PrintF(out, "DICTIONARY_ELEMENTS");
71 break;
72 case NON_STRICT_ARGUMENTS_ELEMENTS:
73 PrintF(out, "NON_STRICT_ARGUMENTS_ELEMENTS");
74 break;
75 case EXTERNAL_BYTE_ELEMENTS:
76 PrintF(out, "EXTERNAL_BYTE_ELEMENTS");
77 break;
78 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
79 PrintF(out, "EXTERNAL_UNSIGNED_BYTE_ELEMENTS");
80 break;
81 case EXTERNAL_SHORT_ELEMENTS:
82 PrintF(out, "EXTERNAL_SHORT_ELEMENTS");
83 break;
84 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
85 PrintF(out, "EXTERNAL_UNSIGNED_SHORT_ELEMENTS");
86 break;
87 case EXTERNAL_INT_ELEMENTS:
88 PrintF(out, "EXTERNAL_INT_ELEMENTS");
89 break;
90 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
91 PrintF(out, "EXTERNAL_UNSIGNED_INT_ELEMENTS");
92 break;
93 case EXTERNAL_FLOAT_ELEMENTS:
94 PrintF(out, "EXTERNAL_FLOAT_ELEMENTS");
95 break;
96 case EXTERNAL_DOUBLE_ELEMENTS:
97 PrintF(out, "EXTERNAL_DOUBLE_ELEMENTS");
98 break;
99 case EXTERNAL_PIXEL_ELEMENTS:
100 PrintF(out, "EXTERNAL_DOUBLE_ELEMENTS");
101 break;
102 }
103 }
104
105
58 // Getters and setters are stored in a fixed array property. These are 106 // Getters and setters are stored in a fixed array property. These are
59 // constants for their indices. 107 // constants for their indices.
60 const int kGetterIndex = 0; 108 const int kGetterIndex = 0;
61 const int kSetterIndex = 1; 109 const int kSetterIndex = 1;
62 110
63 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, 111 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
64 Object* value) { 112 Object* value) {
65 Object* result; 113 Object* result;
66 { MaybeObject* maybe_result = 114 { MaybeObject* maybe_result =
67 constructor->GetHeap()->AllocateJSObject(constructor); 115 constructor->GetHeap()->AllocateJSObject(constructor);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 195 }
148 } 196 }
149 ASSERT(holder != NULL); // Cannot handle null or undefined. 197 ASSERT(holder != NULL); // Cannot handle null or undefined.
150 JSReceiver::cast(holder)->Lookup(name, result); 198 JSReceiver::cast(holder)->Lookup(name, result);
151 } 199 }
152 200
153 201
154 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, 202 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
155 String* name, 203 String* name,
156 PropertyAttributes* attributes) { 204 PropertyAttributes* attributes) {
157 LookupResult result; 205 LookupResult result(name->GetIsolate());
158 Lookup(name, &result); 206 Lookup(name, &result);
159 MaybeObject* value = GetProperty(receiver, &result, name, attributes); 207 MaybeObject* value = GetProperty(receiver, &result, name, attributes);
160 ASSERT(*attributes <= ABSENT); 208 ASSERT(*attributes <= ABSENT);
161 return value; 209 return value;
162 } 210 }
163 211
164 212
165 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, 213 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
166 Object* structure, 214 Object* structure,
167 String* name) { 215 String* name) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 275
228 Handle<Object> args[] = { receiver, name }; 276 Handle<Object> args[] = { receiver, name };
229 Handle<Object> result = CallTrap( 277 Handle<Object> result = CallTrap(
230 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); 278 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
231 if (isolate->has_pending_exception()) return Failure::Exception(); 279 if (isolate->has_pending_exception()) return Failure::Exception();
232 280
233 return *result; 281 return *result;
234 } 282 }
235 283
236 284
285 Handle<Object> Object::GetElement(Handle<Object> object, uint32_t index) {
286 Isolate* isolate = object->IsHeapObject()
287 ? Handle<HeapObject>::cast(object)->GetIsolate()
288 : Isolate::Current();
289 CALL_HEAP_FUNCTION(isolate, object->GetElement(index), Object);
290 }
291
292
237 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, 293 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
238 uint32_t index) { 294 uint32_t index) {
239 String* name; 295 String* name;
240 MaybeObject* maybe = GetHeap()->Uint32ToString(index); 296 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
241 if (!maybe->To<String>(&name)) return maybe; 297 if (!maybe->To<String>(&name)) return maybe;
242 return GetPropertyWithHandler(receiver, name); 298 return GetPropertyWithHandler(receiver, name);
243 } 299 }
244 300
245 301
246 MaybeObject* JSProxy::SetElementWithHandler(uint32_t index, 302 MaybeObject* JSProxy::SetElementWithHandler(uint32_t index,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 return result->holder()->GetPropertyWithCallback( 359 return result->holder()->GetPropertyWithCallback(
304 receiver, result->GetCallbackObject(), name); 360 receiver, result->GetCallbackObject(), name);
305 } 361 }
306 } 362 }
307 break; 363 break;
308 } 364 }
309 case NORMAL: 365 case NORMAL:
310 case FIELD: 366 case FIELD:
311 case CONSTANT_FUNCTION: { 367 case CONSTANT_FUNCTION: {
312 // Search ALL_CAN_READ accessors in prototype chain. 368 // Search ALL_CAN_READ accessors in prototype chain.
313 LookupResult r; 369 LookupResult r(GetIsolate());
314 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 370 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
315 if (r.IsProperty()) { 371 if (r.IsProperty()) {
316 return GetPropertyWithFailedAccessCheck(receiver, 372 return GetPropertyWithFailedAccessCheck(receiver,
317 &r, 373 &r,
318 name, 374 name,
319 attributes); 375 attributes);
320 } 376 }
321 break; 377 break;
322 } 378 }
323 case INTERCEPTOR: { 379 case INTERCEPTOR: {
324 // If the object has an interceptor, try real named properties. 380 // If the object has an interceptor, try real named properties.
325 // No access check in GetPropertyAttributeWithInterceptor. 381 // No access check in GetPropertyAttributeWithInterceptor.
326 LookupResult r; 382 LookupResult r(GetIsolate());
327 result->holder()->LookupRealNamedProperty(name, &r); 383 result->holder()->LookupRealNamedProperty(name, &r);
328 if (r.IsProperty()) { 384 if (r.IsProperty()) {
329 return GetPropertyWithFailedAccessCheck(receiver, 385 return GetPropertyWithFailedAccessCheck(receiver,
330 &r, 386 &r,
331 name, 387 name,
332 attributes); 388 attributes);
333 } 389 }
334 break; 390 break;
335 } 391 }
336 default: 392 default:
(...skipping 26 matching lines...) Expand all
363 } 419 }
364 } 420 }
365 break; 421 break;
366 } 422 }
367 423
368 case NORMAL: 424 case NORMAL:
369 case FIELD: 425 case FIELD:
370 case CONSTANT_FUNCTION: { 426 case CONSTANT_FUNCTION: {
371 if (!continue_search) break; 427 if (!continue_search) break;
372 // Search ALL_CAN_READ accessors in prototype chain. 428 // Search ALL_CAN_READ accessors in prototype chain.
373 LookupResult r; 429 LookupResult r(GetIsolate());
374 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 430 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
375 if (r.IsProperty()) { 431 if (r.IsProperty()) {
376 return GetPropertyAttributeWithFailedAccessCheck(receiver, 432 return GetPropertyAttributeWithFailedAccessCheck(receiver,
377 &r, 433 &r,
378 name, 434 name,
379 continue_search); 435 continue_search);
380 } 436 }
381 break; 437 break;
382 } 438 }
383 439
384 case INTERCEPTOR: { 440 case INTERCEPTOR: {
385 // If the object has an interceptor, try real named properties. 441 // If the object has an interceptor, try real named properties.
386 // No access check in GetPropertyAttributeWithInterceptor. 442 // No access check in GetPropertyAttributeWithInterceptor.
387 LookupResult r; 443 LookupResult r(GetIsolate());
388 if (continue_search) { 444 if (continue_search) {
389 result->holder()->LookupRealNamedProperty(name, &r); 445 result->holder()->LookupRealNamedProperty(name, &r);
390 } else { 446 } else {
391 result->holder()->LocalLookupRealNamedProperty(name, &r); 447 result->holder()->LocalLookupRealNamedProperty(name, &r);
392 } 448 }
393 if (r.IsProperty()) { 449 if (r.IsProperty()) {
394 return GetPropertyAttributeWithFailedAccessCheck(receiver, 450 return GetPropertyAttributeWithFailedAccessCheck(receiver,
395 &r, 451 &r,
396 name, 452 name,
397 continue_search); 453 continue_search);
398 } 454 }
399 break; 455 break;
400 } 456 }
401 457
402 default: 458 default:
403 UNREACHABLE(); 459 UNREACHABLE();
404 } 460 }
405 } 461 }
406 462
407 GetHeap()->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 463 GetIsolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
408 return ABSENT; 464 return ABSENT;
409 } 465 }
410 466
411 467
412 Object* JSObject::GetNormalizedProperty(LookupResult* result) { 468 Object* JSObject::GetNormalizedProperty(LookupResult* result) {
413 ASSERT(!HasFastProperties()); 469 ASSERT(!HasFastProperties());
414 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 470 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
415 if (IsGlobalObject()) { 471 if (IsGlobalObject()) {
416 value = JSGlobalPropertyCell::cast(value)->value(); 472 value = JSGlobalPropertyCell::cast(value)->value();
417 } 473 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 if (!fun->shared()->IsApiFunction()) 577 if (!fun->shared()->IsApiFunction())
522 return true; 578 return true;
523 // If the object is fully fast case and has the same map it was 579 // If the object is fully fast case and has the same map it was
524 // created with then no changes can have been made to it. 580 // created with then no changes can have been made to it.
525 return map() != fun->initial_map() 581 return map() != fun->initial_map()
526 || !HasFastElements() 582 || !HasFastElements()
527 || !HasFastProperties(); 583 || !HasFastProperties();
528 } 584 }
529 585
530 586
587 Handle<Object> Object::GetProperty(Handle<Object> object,
588 Handle<Object> receiver,
589 LookupResult* result,
590 Handle<String> key,
591 PropertyAttributes* attributes) {
592 Isolate* isolate = object->IsHeapObject()
593 ? Handle<HeapObject>::cast(object)->GetIsolate()
594 : Isolate::Current();
595 CALL_HEAP_FUNCTION(
596 isolate,
597 object->GetProperty(*receiver, result, *key, attributes),
598 Object);
599 }
600
601
531 MaybeObject* Object::GetProperty(Object* receiver, 602 MaybeObject* Object::GetProperty(Object* receiver,
532 LookupResult* result, 603 LookupResult* result,
533 String* name, 604 String* name,
534 PropertyAttributes* attributes) { 605 PropertyAttributes* attributes) {
535 // Make sure that the top context does not change when doing 606 // Make sure that the top context does not change when doing
536 // callbacks or interceptor calls. 607 // callbacks or interceptor calls.
537 AssertNoContextChange ncc; 608 AssertNoContextChange ncc;
538 Heap* heap = name->GetHeap(); 609 Heap* heap = name->GetHeap();
539 610
540 // Traverse the prototype chain from the current object (this) to 611 // Traverse the prototype chain from the current object (this) to
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 return context->string_function()->instance_prototype(); 764 return context->string_function()->instance_prototype();
694 } 765 }
695 if (heap_object->IsBoolean()) { 766 if (heap_object->IsBoolean()) {
696 return context->boolean_function()->instance_prototype(); 767 return context->boolean_function()->instance_prototype();
697 } else { 768 } else {
698 return heap->null_value(); 769 return heap->null_value();
699 } 770 }
700 } 771 }
701 772
702 773
774 MaybeObject* Object::GetHash(CreationFlag flag) {
775 // The object is either a number, a string, an odd-ball,
776 // a real JS object, or a Harmony proxy.
777 if (IsNumber()) {
778 uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
779 return Smi::FromInt(hash & Smi::kMaxValue);
780 }
781 if (IsString()) {
782 uint32_t hash = String::cast(this)->Hash();
783 return Smi::FromInt(hash);
784 }
785 if (IsOddball()) {
786 uint32_t hash = Oddball::cast(this)->to_string()->Hash();
787 return Smi::FromInt(hash);
788 }
789 if (IsJSReceiver()) {
790 return JSReceiver::cast(this)->GetIdentityHash(flag);
791 }
792
793 UNREACHABLE();
794 return Smi::FromInt(0);
795 }
796
797
798 bool Object::SameValue(Object* other) {
799 if (other == this) return true;
800 if (!IsHeapObject() || !other->IsHeapObject()) return false;
801
802 // The object is either a number, a string, an odd-ball,
803 // a real JS object, or a Harmony proxy.
804 if (IsNumber() && other->IsNumber()) {
805 double this_value = Number();
806 double other_value = other->Number();
807 return (this_value == other_value) ||
808 (isnan(this_value) && isnan(other_value));
809 }
810 if (IsString() && other->IsString()) {
811 return String::cast(this)->Equals(String::cast(other));
812 }
813 return false;
814 }
815
816
703 void Object::ShortPrint(FILE* out) { 817 void Object::ShortPrint(FILE* out) {
704 HeapStringAllocator allocator; 818 HeapStringAllocator allocator;
705 StringStream accumulator(&allocator); 819 StringStream accumulator(&allocator);
706 ShortPrint(&accumulator); 820 ShortPrint(&accumulator);
707 accumulator.OutputToFile(out); 821 accumulator.OutputToFile(out);
708 } 822 }
709 823
710 824
711 void Object::ShortPrint(StringStream* accumulator) { 825 void Object::ShortPrint(StringStream* accumulator) {
712 if (IsSmi()) { 826 if (IsSmi()) {
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 accumulator->Add(" value = "); 1181 accumulator->Add(" value = ");
1068 JSValue::cast(this)->value()->ShortPrint(accumulator); 1182 JSValue::cast(this)->value()->ShortPrint(accumulator);
1069 } 1183 }
1070 accumulator->Put('>'); 1184 accumulator->Put('>');
1071 break; 1185 break;
1072 } 1186 }
1073 } 1187 }
1074 } 1188 }
1075 1189
1076 1190
1191 void JSObject::PrintElementsTransition(
1192 FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
1193 ElementsKind to_kind, FixedArrayBase* to_elements) {
1194 if (from_kind != to_kind) {
1195 PrintF(file, "elements transition [");
1196 PrintElementsKind(file, from_kind);
1197 PrintF(file, " -> ");
1198 PrintElementsKind(file, to_kind);
1199 PrintF(file, "] in ");
1200 JavaScriptFrame::PrintTop(file, false, true);
1201 PrintF(file, " for ");
1202 ShortPrint(file);
1203 PrintF(file, " from ");
1204 from_elements->ShortPrint(file);
1205 PrintF(file, " to ");
1206 to_elements->ShortPrint(file);
1207 PrintF(file, "\n");
1208 }
1209 }
1210
1211
1077 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { 1212 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
1078 Heap* heap = GetHeap(); 1213 Heap* heap = GetHeap();
1079 if (!heap->Contains(this)) { 1214 if (!heap->Contains(this)) {
1080 accumulator->Add("!!!INVALID POINTER!!!"); 1215 accumulator->Add("!!!INVALID POINTER!!!");
1081 return; 1216 return;
1082 } 1217 }
1083 if (!heap->Contains(map())) { 1218 if (!heap->Contains(map())) {
1084 accumulator->Add("!!!INVALID MAP!!!"); 1219 accumulator->Add("!!!INVALID MAP!!!");
1085 return; 1220 return;
1086 } 1221 }
1087 1222
1088 accumulator->Add("%p ", this); 1223 accumulator->Add("%p ", this);
1089 1224
1090 if (IsString()) { 1225 if (IsString()) {
1091 String::cast(this)->StringShortPrint(accumulator); 1226 String::cast(this)->StringShortPrint(accumulator);
1092 return; 1227 return;
1093 } 1228 }
1094 if (IsJSObject()) { 1229 if (IsJSObject()) {
1095 JSObject::cast(this)->JSObjectShortPrint(accumulator); 1230 JSObject::cast(this)->JSObjectShortPrint(accumulator);
1096 return; 1231 return;
1097 } 1232 }
1098 switch (map()->instance_type()) { 1233 switch (map()->instance_type()) {
1099 case MAP_TYPE: 1234 case MAP_TYPE:
1100 accumulator->Add("<Map(elements=%u)>", Map::cast(this)->elements_kind()); 1235 accumulator->Add("<Map(elements=%u)>", Map::cast(this)->elements_kind());
1101 break; 1236 break;
1102 case FIXED_ARRAY_TYPE: 1237 case FIXED_ARRAY_TYPE:
1103 accumulator->Add("<FixedArray[%u]>", FixedArray::cast(this)->length()); 1238 accumulator->Add("<FixedArray[%u]>", FixedArray::cast(this)->length());
1104 break; 1239 break;
1240 case FIXED_DOUBLE_ARRAY_TYPE:
1241 accumulator->Add("<FixedDoubleArray[%u]>",
1242 FixedDoubleArray::cast(this)->length());
1243 break;
1105 case BYTE_ARRAY_TYPE: 1244 case BYTE_ARRAY_TYPE:
1106 accumulator->Add("<ByteArray[%u]>", ByteArray::cast(this)->length()); 1245 accumulator->Add("<ByteArray[%u]>", ByteArray::cast(this)->length());
1107 break; 1246 break;
1108 case FREE_SPACE_TYPE: 1247 case FREE_SPACE_TYPE:
1109 accumulator->Add("<FreeSpace[%u]>", FreeSpace::cast(this)->Size()); 1248 accumulator->Add("<FreeSpace[%u]>", FreeSpace::cast(this)->Size());
1110 break; 1249 break;
1111 case EXTERNAL_PIXEL_ARRAY_TYPE: 1250 case EXTERNAL_PIXEL_ARRAY_TYPE:
1112 accumulator->Add("<ExternalPixelArray[%u]>", 1251 accumulator->Add("<ExternalPixelArray[%u]>",
1113 ExternalPixelArray::cast(this)->length()); 1252 ExternalPixelArray::cast(this)->length());
1114 break; 1253 break;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 switch (type) { 1379 switch (type) {
1241 case FIXED_ARRAY_TYPE: 1380 case FIXED_ARRAY_TYPE:
1242 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); 1381 FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1243 break; 1382 break;
1244 case FIXED_DOUBLE_ARRAY_TYPE: 1383 case FIXED_DOUBLE_ARRAY_TYPE:
1245 break; 1384 break;
1246 case JS_OBJECT_TYPE: 1385 case JS_OBJECT_TYPE:
1247 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 1386 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1248 case JS_VALUE_TYPE: 1387 case JS_VALUE_TYPE:
1249 case JS_ARRAY_TYPE: 1388 case JS_ARRAY_TYPE:
1389 case JS_SET_TYPE:
1390 case JS_MAP_TYPE:
1250 case JS_WEAK_MAP_TYPE: 1391 case JS_WEAK_MAP_TYPE:
1251 case JS_REGEXP_TYPE: 1392 case JS_REGEXP_TYPE:
1252 case JS_GLOBAL_PROXY_TYPE: 1393 case JS_GLOBAL_PROXY_TYPE:
1253 case JS_GLOBAL_OBJECT_TYPE: 1394 case JS_GLOBAL_OBJECT_TYPE:
1254 case JS_BUILTINS_OBJECT_TYPE: 1395 case JS_BUILTINS_OBJECT_TYPE:
1255 case JS_MESSAGE_OBJECT_TYPE: 1396 case JS_MESSAGE_OBJECT_TYPE:
1256 JSObject::BodyDescriptor::IterateBody(this, object_size, v); 1397 JSObject::BodyDescriptor::IterateBody(this, object_size, v);
1257 break; 1398 break;
1258 case JS_FUNCTION_TYPE: 1399 case JS_FUNCTION_TYPE:
1259 reinterpret_cast<JSFunction*>(this) 1400 reinterpret_cast<JSFunction*>(this)
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 return AddSlowProperty(name, value, attributes); 1792 return AddSlowProperty(name, value, attributes);
1652 } 1793 }
1653 1794
1654 1795
1655 MaybeObject* JSObject::SetPropertyPostInterceptor( 1796 MaybeObject* JSObject::SetPropertyPostInterceptor(
1656 String* name, 1797 String* name,
1657 Object* value, 1798 Object* value,
1658 PropertyAttributes attributes, 1799 PropertyAttributes attributes,
1659 StrictModeFlag strict_mode) { 1800 StrictModeFlag strict_mode) {
1660 // Check local property, ignore interceptor. 1801 // Check local property, ignore interceptor.
1661 LookupResult result; 1802 LookupResult result(GetIsolate());
1662 LocalLookupRealNamedProperty(name, &result); 1803 LocalLookupRealNamedProperty(name, &result);
1663 if (result.IsFound()) { 1804 if (result.IsFound()) {
1664 // An existing property, a map transition or a null descriptor was 1805 // An existing property, a map transition or a null descriptor was
1665 // found. Use set property to handle all these cases. 1806 // found. Use set property to handle all these cases.
1666 return SetProperty(&result, name, value, attributes, strict_mode); 1807 return SetProperty(&result, name, value, attributes, strict_mode);
1667 } 1808 }
1668 bool found = false; 1809 bool found = false;
1669 MaybeObject* result_object; 1810 MaybeObject* result_object;
1670 result_object = SetPropertyWithCallbackSetterInPrototypes(name, 1811 result_object = SetPropertyWithCallbackSetterInPrototypes(name,
1671 value, 1812 value,
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 strict_mode); 1974 strict_mode);
1834 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1975 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1835 return raw_result; 1976 return raw_result;
1836 } 1977 }
1837 1978
1838 1979
1839 MaybeObject* JSReceiver::SetProperty(String* name, 1980 MaybeObject* JSReceiver::SetProperty(String* name,
1840 Object* value, 1981 Object* value,
1841 PropertyAttributes attributes, 1982 PropertyAttributes attributes,
1842 StrictModeFlag strict_mode) { 1983 StrictModeFlag strict_mode) {
1843 LookupResult result; 1984 LookupResult result(GetIsolate());
1844 LocalLookup(name, &result); 1985 LocalLookup(name, &result);
1845 return SetProperty(&result, name, value, attributes, strict_mode); 1986 return SetProperty(&result, name, value, attributes, strict_mode);
1846 } 1987 }
1847 1988
1848 1989
1849 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, 1990 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
1850 String* name, 1991 String* name,
1851 Object* value, 1992 Object* value,
1852 JSObject* holder, 1993 JSObject* holder,
1853 StrictModeFlag strict_mode) { 1994 StrictModeFlag strict_mode) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 *found = false; 2140 *found = false;
2000 return heap->the_hole_value(); 2141 return heap->the_hole_value();
2001 } 2142 }
2002 2143
2003 MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes( 2144 MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes(
2004 String* name, 2145 String* name,
2005 Object* value, 2146 Object* value,
2006 PropertyAttributes attributes, 2147 PropertyAttributes attributes,
2007 bool* found, 2148 bool* found,
2008 StrictModeFlag strict_mode) { 2149 StrictModeFlag strict_mode) {
2009 LookupResult result; 2150 Heap* heap = GetHeap();
2151 LookupResult result(heap->isolate());
2010 LookupCallbackSetterInPrototypes(name, &result); 2152 LookupCallbackSetterInPrototypes(name, &result);
2011 Heap* heap = GetHeap();
2012 if (result.IsFound()) { 2153 if (result.IsFound()) {
2013 *found = true; 2154 *found = true;
2014 if (result.type() == CALLBACKS) { 2155 if (result.type() == CALLBACKS) {
2015 return SetPropertyWithCallback(result.GetCallbackObject(), 2156 return SetPropertyWithCallback(result.GetCallbackObject(),
2016 name, 2157 name,
2017 value, 2158 value,
2018 result.holder(), 2159 result.holder(),
2019 strict_mode); 2160 strict_mode);
2020 } else if (result.type() == HANDLER) { 2161 } else if (result.type() == HANDLER) {
2021 // We could not find a local property so let's check whether there is an 2162 // We could not find a local property so let's check whether there is an
2022 // accessor that wants to handle the property. 2163 // accessor that wants to handle the property.
2023 LookupResult accessor_result; 2164 LookupResult accessor_result(heap->isolate());
2024 LookupCallbackSetterInPrototypes(name, &accessor_result); 2165 LookupCallbackSetterInPrototypes(name, &accessor_result);
2025 if (accessor_result.IsFound()) { 2166 if (accessor_result.IsFound()) {
2026 if (accessor_result.type() == CALLBACKS) { 2167 if (accessor_result.type() == CALLBACKS) {
2027 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), 2168 return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
2028 name, 2169 name,
2029 value, 2170 value,
2030 accessor_result.holder(), 2171 accessor_result.holder(),
2031 strict_mode); 2172 strict_mode);
2032 } else if (accessor_result.type() == HANDLER) { 2173 } else if (accessor_result.type() == HANDLER) {
2033 // There is a proxy in the prototype chain. Invoke its 2174 // There is a proxy in the prototype chain. Invoke its
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 cache->Update(descriptors, name, number); 2219 cache->Update(descriptors, name, number);
2079 } 2220 }
2080 if (number != DescriptorArray::kNotFound) { 2221 if (number != DescriptorArray::kNotFound) {
2081 result->DescriptorResult(holder, descriptors->GetDetails(number), number); 2222 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2082 } else { 2223 } else {
2083 result->NotFound(); 2224 result->NotFound();
2084 } 2225 }
2085 } 2226 }
2086 2227
2087 2228
2229 static bool ContainsMap(MapHandleList* maps, Handle<Map> map) {
2230 ASSERT(!map.is_null());
2231 for (int i = 0; i < maps->length(); ++i) {
2232 if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true;
2233 }
2234 return false;
2235 }
2236
2237
2238 template <class T>
2239 static Handle<T> MaybeNull(T* p) {
2240 if (p == NULL) return Handle<T>::null();
2241 return Handle<T>(p);
2242 }
2243
2244
2245 Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
2246 ElementsKind elms_kind = elements_kind();
2247 if (elms_kind == FAST_DOUBLE_ELEMENTS) {
2248 bool dummy = true;
2249 Handle<Map> fast_map =
2250 MaybeNull(LookupElementsTransitionMap(FAST_ELEMENTS, &dummy));
2251 if (!fast_map.is_null() && ContainsMap(candidates, fast_map)) {
2252 return fast_map;
2253 }
2254 return Handle<Map>::null();
2255 }
2256 if (elms_kind == FAST_SMI_ONLY_ELEMENTS) {
2257 bool dummy = true;
2258 Handle<Map> double_map =
2259 MaybeNull(LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, &dummy));
2260 // In the current implementation, if the DOUBLE map doesn't exist, the
2261 // FAST map can't exist either.
2262 if (double_map.is_null()) return Handle<Map>::null();
2263 Handle<Map> fast_map =
2264 MaybeNull(double_map->LookupElementsTransitionMap(FAST_ELEMENTS,
2265 &dummy));
2266 if (!fast_map.is_null() && ContainsMap(candidates, fast_map)) {
2267 return fast_map;
2268 }
2269 if (ContainsMap(candidates, double_map)) return double_map;
2270 }
2271 return Handle<Map>::null();
2272 }
2273
2088 static Map* GetElementsTransitionMapFromDescriptor(Object* descriptor_contents, 2274 static Map* GetElementsTransitionMapFromDescriptor(Object* descriptor_contents,
2089 ElementsKind elements_kind) { 2275 ElementsKind elements_kind) {
2090 if (descriptor_contents->IsMap()) { 2276 if (descriptor_contents->IsMap()) {
2091 Map* map = Map::cast(descriptor_contents); 2277 Map* map = Map::cast(descriptor_contents);
2092 if (map->elements_kind() == elements_kind) { 2278 if (map->elements_kind() == elements_kind) {
2093 return map; 2279 return map;
2094 } 2280 }
2095 return NULL; 2281 return NULL;
2096 } 2282 }
2097 2283
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 MaybeObject* maybe_new_descriptors = 2447 MaybeObject* maybe_new_descriptors =
2262 instance_descriptors()->CopyInsert(&desc, KEEP_TRANSITIONS); 2448 instance_descriptors()->CopyInsert(&desc, KEEP_TRANSITIONS);
2263 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { 2449 if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
2264 return maybe_new_descriptors; 2450 return maybe_new_descriptors;
2265 } 2451 }
2266 set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 2452 set_instance_descriptors(DescriptorArray::cast(new_descriptors));
2267 return this; 2453 return this;
2268 } 2454 }
2269 2455
2270 2456
2457 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
2458 ElementsKind to_kind) {
2459 Isolate* isolate = object->GetIsolate();
2460 CALL_HEAP_FUNCTION(isolate,
2461 object->GetElementsTransitionMap(to_kind),
2462 Map);
2463 }
2464
2465
2271 MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind to_kind) { 2466 MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind to_kind) {
2272 Map* current_map = map(); 2467 Map* current_map = map();
2273 ElementsKind from_kind = current_map->elements_kind(); 2468 ElementsKind from_kind = current_map->elements_kind();
2274 2469
2275 if (from_kind == to_kind) return current_map; 2470 if (from_kind == to_kind) return current_map;
2276 2471
2277 // Only objects with FastProperties can have DescriptorArrays and can track 2472 // Only objects with FastProperties can have DescriptorArrays and can track
2278 // element-related maps. Also don't add descriptors to maps that are shared. 2473 // element-related maps. Also don't add descriptors to maps that are shared.
2279 bool safe_to_add_transition = HasFastProperties() && 2474 bool safe_to_add_transition = HasFastProperties() &&
2280 !current_map->IsUndefined() && 2475 !current_map->IsUndefined() &&
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2416 value, 2611 value,
2417 result->holder(), 2612 result->holder(),
2418 strict_mode); 2613 strict_mode);
2419 } 2614 }
2420 } 2615 }
2421 break; 2616 break;
2422 } 2617 }
2423 case INTERCEPTOR: { 2618 case INTERCEPTOR: {
2424 // Try lookup real named properties. Note that only property can be 2619 // Try lookup real named properties. Note that only property can be
2425 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. 2620 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
2426 LookupResult r; 2621 LookupResult r(GetIsolate());
2427 LookupRealNamedProperty(name, &r); 2622 LookupRealNamedProperty(name, &r);
2428 if (r.IsProperty()) { 2623 if (r.IsProperty()) {
2429 return SetPropertyWithFailedAccessCheck(&r, 2624 return SetPropertyWithFailedAccessCheck(&r,
2430 name, 2625 name,
2431 value, 2626 value,
2432 check_prototype, 2627 check_prototype,
2433 strict_mode); 2628 strict_mode);
2434 } 2629 }
2435 break; 2630 break;
2436 } 2631 }
2437 default: { 2632 default: {
2438 break; 2633 break;
2439 } 2634 }
2440 } 2635 }
2441 } 2636 }
2442 } 2637 }
2443 2638
2444 Heap* heap = GetHeap(); 2639 Isolate* isolate = GetIsolate();
2445 HandleScope scope(heap->isolate()); 2640 HandleScope scope(isolate);
2446 Handle<Object> value_handle(value); 2641 Handle<Object> value_handle(value);
2447 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); 2642 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
2448 return *value_handle; 2643 return *value_handle;
2449 } 2644 }
2450 2645
2451 2646
2452 MaybeObject* JSReceiver::SetProperty(LookupResult* result, 2647 MaybeObject* JSReceiver::SetProperty(LookupResult* result,
2453 String* key, 2648 String* key,
2454 Object* value, 2649 Object* value,
2455 PropertyAttributes attributes, 2650 PropertyAttributes attributes,
2456 StrictModeFlag strict_mode) { 2651 StrictModeFlag strict_mode) {
2457 if (result->IsFound() && result->type() == HANDLER) { 2652 if (result->IsFound() && result->type() == HANDLER) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2500 2695
2501 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( 2696 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
2502 String* name_raw, 2697 String* name_raw,
2503 Object* value_raw, 2698 Object* value_raw,
2504 PropertyAttributes attributes, 2699 PropertyAttributes attributes,
2505 StrictModeFlag strict_mode, 2700 StrictModeFlag strict_mode,
2506 bool* found) { 2701 bool* found) {
2507 *found = true; // except where defined otherwise... 2702 *found = true; // except where defined otherwise...
2508 Isolate* isolate = GetHeap()->isolate(); 2703 Isolate* isolate = GetHeap()->isolate();
2509 Handle<JSProxy> proxy(this); 2704 Handle<JSProxy> proxy(this);
2705 Handle<Object> handler(this->handler()); // Trap might morph proxy.
2510 Handle<String> name(name_raw); 2706 Handle<String> name(name_raw);
2511 Handle<Object> value(value_raw); 2707 Handle<Object> value(value_raw);
2512 Handle<Object> args[] = { name }; 2708 Handle<Object> args[] = { name };
2513 Handle<Object> result = proxy->CallTrap( 2709 Handle<Object> result = proxy->CallTrap(
2514 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 2710 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
2515 if (isolate->has_pending_exception()) return Failure::Exception(); 2711 if (isolate->has_pending_exception()) return Failure::Exception();
2516 2712
2517 if (!result->IsUndefined()) { 2713 if (!result->IsUndefined()) {
2518 // The proxy handler cares about this property. 2714 // The proxy handler cares about this property.
2519 // Check whether it is virtualized as an accessor. 2715 // Check whether it is virtualized as an accessor.
2520 // Emulate [[GetProperty]] semantics for proxies. 2716 // Emulate [[GetProperty]] semantics for proxies.
2521 bool has_pending_exception; 2717 bool has_pending_exception;
2522 Handle<Object> argv[] = { result }; 2718 Handle<Object> argv[] = { result };
2523 Handle<Object> desc = 2719 Handle<Object> desc =
2524 Execution::Call(isolate->to_complete_property_descriptor(), result, 2720 Execution::Call(isolate->to_complete_property_descriptor(), result,
2525 ARRAY_SIZE(argv), argv, &has_pending_exception); 2721 ARRAY_SIZE(argv), argv, &has_pending_exception);
2526 if (has_pending_exception) return Failure::Exception(); 2722 if (has_pending_exception) return Failure::Exception();
2527 2723
2528 Handle<String> conf_name = 2724 Handle<String> conf_name =
2529 isolate->factory()->LookupAsciiSymbol("configurable_"); 2725 isolate->factory()->LookupAsciiSymbol("configurable_");
2530 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name)); 2726 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name));
2531 ASSERT(!isolate->has_pending_exception()); 2727 ASSERT(!isolate->has_pending_exception());
2532 if (configurable->IsFalse()) { 2728 if (configurable->IsFalse()) {
2533 Handle<Object> args[] = { Handle<Object>(proxy->handler()), proxy, name }; 2729 Handle<String> trap =
2730 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
2731 Handle<Object> args[] = { handler, trap, name };
2534 Handle<Object> error = isolate->factory()->NewTypeError( 2732 Handle<Object> error = isolate->factory()->NewTypeError(
2535 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); 2733 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
2536 return isolate->Throw(*error); 2734 return isolate->Throw(*error);
2537 } 2735 }
2538 ASSERT(configurable->IsTrue()); 2736 ASSERT(configurable->IsTrue());
2539 2737
2540 // Check for AccessorDescriptor. 2738 // Check for AccessorDescriptor.
2541 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_"); 2739 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_");
2542 Handle<Object> setter(v8::internal::GetProperty(desc, set_name)); 2740 Handle<Object> setter(v8::internal::GetProperty(desc, set_name));
2543 ASSERT(!isolate->has_pending_exception()); 2741 ASSERT(!isolate->has_pending_exception());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2603 return JSProxy::DeletePropertyWithHandler(*name, mode); 2801 return JSProxy::DeletePropertyWithHandler(*name, mode);
2604 } 2802 }
2605 2803
2606 2804
2607 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( 2805 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
2608 JSReceiver* receiver_raw, 2806 JSReceiver* receiver_raw,
2609 String* name_raw) { 2807 String* name_raw) {
2610 Isolate* isolate = GetIsolate(); 2808 Isolate* isolate = GetIsolate();
2611 HandleScope scope(isolate); 2809 HandleScope scope(isolate);
2612 Handle<JSProxy> proxy(this); 2810 Handle<JSProxy> proxy(this);
2811 Handle<Object> handler(this->handler()); // Trap might morph proxy.
2613 Handle<JSReceiver> receiver(receiver_raw); 2812 Handle<JSReceiver> receiver(receiver_raw);
2614 Handle<Object> name(name_raw); 2813 Handle<Object> name(name_raw);
2615 2814
2616 Handle<Object> args[] = { name }; 2815 Handle<Object> args[] = { name };
2617 Handle<Object> result = CallTrap( 2816 Handle<Object> result = CallTrap(
2618 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 2817 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
2619 if (isolate->has_pending_exception()) return NONE; 2818 if (isolate->has_pending_exception()) return NONE;
2620 2819
2621 if (result->IsUndefined()) return ABSENT; 2820 if (result->IsUndefined()) return ABSENT;
2622 2821
2623 bool has_pending_exception; 2822 bool has_pending_exception;
2624 Handle<Object> argv[] = { result }; 2823 Handle<Object> argv[] = { result };
2625 Handle<Object> desc = 2824 Handle<Object> desc =
2626 Execution::Call(isolate->to_complete_property_descriptor(), result, 2825 Execution::Call(isolate->to_complete_property_descriptor(), result,
2627 ARRAY_SIZE(argv), argv, &has_pending_exception); 2826 ARRAY_SIZE(argv), argv, &has_pending_exception);
2628 if (has_pending_exception) return NONE; 2827 if (has_pending_exception) return NONE;
2629 2828
2630 // Convert result to PropertyAttributes. 2829 // Convert result to PropertyAttributes.
2631 Handle<String> enum_n = isolate->factory()->LookupAsciiSymbol("enumerable"); 2830 Handle<String> enum_n = isolate->factory()->LookupAsciiSymbol("enumerable");
2632 Handle<Object> enumerable(v8::internal::GetProperty(desc, enum_n)); 2831 Handle<Object> enumerable(v8::internal::GetProperty(desc, enum_n));
2633 if (isolate->has_pending_exception()) return NONE; 2832 if (isolate->has_pending_exception()) return NONE;
2634 Handle<String> conf_n = isolate->factory()->LookupAsciiSymbol("configurable"); 2833 Handle<String> conf_n = isolate->factory()->LookupAsciiSymbol("configurable");
2635 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_n)); 2834 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_n));
2636 if (isolate->has_pending_exception()) return NONE; 2835 if (isolate->has_pending_exception()) return NONE;
2637 Handle<String> writ_n = isolate->factory()->LookupAsciiSymbol("writable"); 2836 Handle<String> writ_n = isolate->factory()->LookupAsciiSymbol("writable");
2638 Handle<Object> writable(v8::internal::GetProperty(desc, writ_n)); 2837 Handle<Object> writable(v8::internal::GetProperty(desc, writ_n));
2639 if (isolate->has_pending_exception()) return NONE; 2838 if (isolate->has_pending_exception()) return NONE;
2640 2839
2641 if (configurable->IsFalse()) { 2840 if (configurable->IsFalse()) {
2642 Handle<Object> args[] = { Handle<Object>(proxy->handler()), proxy, name }; 2841 Handle<String> trap =
2842 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
2843 Handle<Object> args[] = { handler, trap, name };
2643 Handle<Object> error = isolate->factory()->NewTypeError( 2844 Handle<Object> error = isolate->factory()->NewTypeError(
2644 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); 2845 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
2645 isolate->Throw(*error); 2846 isolate->Throw(*error);
2646 return NONE; 2847 return NONE;
2647 } 2848 }
2648 2849
2649 int attributes = NONE; 2850 int attributes = NONE;
2650 if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM; 2851 if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM;
2651 if (configurable->ToBoolean()->IsFalse()) attributes |= DONT_DELETE; 2852 if (configurable->ToBoolean()->IsFalse()) attributes |= DONT_DELETE;
2652 if (writable->ToBoolean()->IsFalse()) attributes |= READ_ONLY; 2853 if (writable->ToBoolean()->IsFalse()) attributes |= READ_ONLY;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2852 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" 3053 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
2853 // doesn't handle function prototypes correctly. 3054 // doesn't handle function prototypes correctly.
2854 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( 3055 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
2855 String* name, 3056 String* name,
2856 Object* value, 3057 Object* value,
2857 PropertyAttributes attributes) { 3058 PropertyAttributes attributes) {
2858 3059
2859 // Make sure that the top context does not change when doing callbacks or 3060 // Make sure that the top context does not change when doing callbacks or
2860 // interceptor calls. 3061 // interceptor calls.
2861 AssertNoContextChange ncc; 3062 AssertNoContextChange ncc;
2862 LookupResult result; 3063 Isolate* isolate = GetIsolate();
3064 LookupResult result(isolate);
2863 LocalLookup(name, &result); 3065 LocalLookup(name, &result);
2864 // Check access rights if needed. 3066 // Check access rights if needed.
2865 if (IsAccessCheckNeeded()) { 3067 if (IsAccessCheckNeeded()) {
2866 Heap* heap = GetHeap(); 3068 if (!isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
2867 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
2868 return SetPropertyWithFailedAccessCheck(&result, 3069 return SetPropertyWithFailedAccessCheck(&result,
2869 name, 3070 name,
2870 value, 3071 value,
2871 false, 3072 false,
2872 kNonStrictMode); 3073 kNonStrictMode);
2873 } 3074 }
2874 } 3075 }
2875 3076
2876 if (IsJSGlobalProxy()) { 3077 if (IsJSGlobalProxy()) {
2877 Object* proto = GetPrototype(); 3078 Object* proto = GetPrototype();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2928 UNREACHABLE(); 3129 UNREACHABLE();
2929 return value; 3130 return value;
2930 } 3131 }
2931 3132
2932 3133
2933 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 3134 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
2934 JSObject* receiver, 3135 JSObject* receiver,
2935 String* name, 3136 String* name,
2936 bool continue_search) { 3137 bool continue_search) {
2937 // Check local property, ignore interceptor. 3138 // Check local property, ignore interceptor.
2938 LookupResult result; 3139 LookupResult result(GetIsolate());
2939 LocalLookupRealNamedProperty(name, &result); 3140 LocalLookupRealNamedProperty(name, &result);
2940 if (result.IsProperty()) return result.GetAttributes(); 3141 if (result.IsProperty()) return result.GetAttributes();
2941 3142
2942 if (continue_search) { 3143 if (continue_search) {
2943 // Continue searching via the prototype chain. 3144 // Continue searching via the prototype chain.
2944 Object* pt = GetPrototype(); 3145 Object* pt = GetPrototype();
2945 if (!pt->IsNull()) { 3146 if (!pt->IsNull()) {
2946 return JSObject::cast(pt)-> 3147 return JSObject::cast(pt)->
2947 GetPropertyAttributeWithReceiver(receiver, name); 3148 GetPropertyAttributeWithReceiver(receiver, name);
2948 } 3149 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 3205
3005 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( 3206 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
3006 JSReceiver* receiver, 3207 JSReceiver* receiver,
3007 String* key) { 3208 String* key) {
3008 uint32_t index = 0; 3209 uint32_t index = 0;
3009 if (IsJSObject() && key->AsArrayIndex(&index)) { 3210 if (IsJSObject() && key->AsArrayIndex(&index)) {
3010 return JSObject::cast(this)->HasElementWithReceiver(receiver, index) 3211 return JSObject::cast(this)->HasElementWithReceiver(receiver, index)
3011 ? NONE : ABSENT; 3212 ? NONE : ABSENT;
3012 } 3213 }
3013 // Named property. 3214 // Named property.
3014 LookupResult result; 3215 LookupResult result(GetIsolate());
3015 Lookup(key, &result); 3216 Lookup(key, &result);
3016 return GetPropertyAttribute(receiver, &result, key, true); 3217 return GetPropertyAttribute(receiver, &result, key, true);
3017 } 3218 }
3018 3219
3019 3220
3020 PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver, 3221 PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
3021 LookupResult* result, 3222 LookupResult* result,
3022 String* name, 3223 String* name,
3023 bool continue_search) { 3224 bool continue_search) {
3024 // Check access rights if needed. 3225 // Check access rights if needed.
(...skipping 28 matching lines...) Expand all
3053 3254
3054 3255
3055 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) { 3256 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) {
3056 // Check whether the name is an array index. 3257 // Check whether the name is an array index.
3057 uint32_t index = 0; 3258 uint32_t index = 0;
3058 if (IsJSObject() && name->AsArrayIndex(&index)) { 3259 if (IsJSObject() && name->AsArrayIndex(&index)) {
3059 if (JSObject::cast(this)->HasLocalElement(index)) return NONE; 3260 if (JSObject::cast(this)->HasLocalElement(index)) return NONE;
3060 return ABSENT; 3261 return ABSENT;
3061 } 3262 }
3062 // Named property. 3263 // Named property.
3063 LookupResult result; 3264 LookupResult result(GetIsolate());
3064 LocalLookup(name, &result); 3265 LocalLookup(name, &result);
3065 return GetPropertyAttribute(this, &result, name, false); 3266 return GetPropertyAttribute(this, &result, name, false);
3066 } 3267 }
3067 3268
3068 3269
3069 MaybeObject* NormalizedMapCache::Get(JSObject* obj, 3270 MaybeObject* NormalizedMapCache::Get(JSObject* obj,
3070 PropertyNormalizationMode mode) { 3271 PropertyNormalizationMode mode) {
3071 Isolate* isolate = obj->GetIsolate(); 3272 Isolate* isolate = obj->GetIsolate();
3072 Map* fast = obj->map(); 3273 Map* fast = obj->map();
3073 int index = fast->Hash() % kEntries; 3274 int index = fast->Hash() % kEntries;
3074 Object* result = get(index); 3275 Object* result = get(index);
3075 if (result->IsMap() && 3276 if (result->IsMap() &&
3076 Map::cast(result)->EquivalentToForNormalization(fast, mode)) { 3277 Map::cast(result)->EquivalentToForNormalization(fast, mode)) {
3077 #ifdef DEBUG 3278 #ifdef DEBUG
3078 Map::cast(result)->SharedMapVerify(); 3279 if (FLAG_verify_heap) {
3280 Map::cast(result)->SharedMapVerify();
3281 }
3079 if (FLAG_enable_slow_asserts) { 3282 if (FLAG_enable_slow_asserts) {
3080 // The cached map should match newly created normalized map bit-by-bit. 3283 // The cached map should match newly created normalized map bit-by-bit.
3081 Object* fresh; 3284 Object* fresh;
3082 { MaybeObject* maybe_fresh = 3285 { MaybeObject* maybe_fresh =
3083 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); 3286 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
3084 if (maybe_fresh->ToObject(&fresh)) { 3287 if (maybe_fresh->ToObject(&fresh)) {
3085 ASSERT(memcmp(Map::cast(fresh)->address(), 3288 ASSERT(memcmp(Map::cast(fresh)->address(),
3086 Map::cast(result)->address(), 3289 Map::cast(result)->address(),
3087 Map::kSize) == 0); 3290 Map::kSize) == 0);
3088 } 3291 }
(...skipping 15 matching lines...) Expand all
3104 3307
3105 3308
3106 void NormalizedMapCache::Clear() { 3309 void NormalizedMapCache::Clear() {
3107 int entries = length(); 3310 int entries = length();
3108 for (int i = 0; i != entries; i++) { 3311 for (int i = 0; i != entries; i++) {
3109 set_undefined(i); 3312 set_undefined(i);
3110 } 3313 }
3111 } 3314 }
3112 3315
3113 3316
3317 void JSObject::UpdateMapCodeCache(Handle<JSObject> object,
3318 Handle<String> name,
3319 Handle<Code> code) {
3320 Isolate* isolate = object->GetIsolate();
3321 CALL_HEAP_FUNCTION_VOID(isolate,
3322 object->UpdateMapCodeCache(*name, *code));
3323 }
3324
3325
3114 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) { 3326 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) {
3115 if (map()->is_shared()) { 3327 if (map()->is_shared()) {
3116 // Fast case maps are never marked as shared. 3328 // Fast case maps are never marked as shared.
3117 ASSERT(!HasFastProperties()); 3329 ASSERT(!HasFastProperties());
3118 // Replace the map with an identical copy that can be safely modified. 3330 // Replace the map with an identical copy that can be safely modified.
3119 Object* obj; 3331 Object* obj;
3120 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, 3332 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
3121 UNIQUE_NORMALIZED_MAP); 3333 UNIQUE_NORMALIZED_MAP);
3122 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3334 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3123 } 3335 }
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 3561
3350 3562
3351 Smi* JSReceiver::GenerateIdentityHash() { 3563 Smi* JSReceiver::GenerateIdentityHash() {
3352 Isolate* isolate = GetIsolate(); 3564 Isolate* isolate = GetIsolate();
3353 3565
3354 int hash_value; 3566 int hash_value;
3355 int attempts = 0; 3567 int attempts = 0;
3356 do { 3568 do {
3357 // Generate a random 32-bit hash value but limit range to fit 3569 // Generate a random 32-bit hash value but limit range to fit
3358 // within a smi. 3570 // within a smi.
3359 hash_value = V8::Random(isolate) & Smi::kMaxValue; 3571 hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue;
3360 attempts++; 3572 attempts++;
3361 } while (hash_value == 0 && attempts < 30); 3573 } while (hash_value == 0 && attempts < 30);
3362 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 3574 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
3363 3575
3364 return Smi::FromInt(hash_value); 3576 return Smi::FromInt(hash_value);
3365 } 3577 }
3366 3578
3367 3579
3368 MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) { 3580 MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) {
3369 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), 3581 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(),
3370 hash); 3582 hash);
3371 if (maybe->IsFailure()) return maybe; 3583 if (maybe->IsFailure()) return maybe;
3372 return this; 3584 return this;
3373 } 3585 }
3374 3586
3375 3587
3376 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { 3588 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) {
3377 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol()); 3589 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol());
3378 if (stored_value->IsSmi()) return stored_value; 3590 if (stored_value->IsSmi()) return stored_value;
3379 3591
3592 // Do not generate permanent identity hash code if not requested.
3593 if (flag == OMIT_CREATION) return GetHeap()->undefined_value();
3594
3380 Smi* hash = GenerateIdentityHash(); 3595 Smi* hash = GenerateIdentityHash();
3381 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_symbol(), 3596 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_symbol(),
3382 hash); 3597 hash);
3383 if (result->IsFailure()) return result; 3598 if (result->IsFailure()) return result;
3384 if (result->ToObjectUnchecked()->IsUndefined()) { 3599 if (result->ToObjectUnchecked()->IsUndefined()) {
3385 // Trying to get hash of detached proxy. 3600 // Trying to get hash of detached proxy.
3386 return Smi::FromInt(0); 3601 return Smi::FromInt(0);
3387 } 3602 }
3388 return hash; 3603 return hash;
3389 } 3604 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
3560 DONT_ENUM, 3775 DONT_ENUM,
3561 kNonStrictMode); 3776 kNonStrictMode);
3562 if (store_result->IsFailure()) return store_result; 3777 if (store_result->IsFailure()) return store_result;
3563 return this; 3778 return this;
3564 } 3779 }
3565 3780
3566 3781
3567 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 3782 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
3568 DeleteMode mode) { 3783 DeleteMode mode) {
3569 // Check local property, ignore interceptor. 3784 // Check local property, ignore interceptor.
3570 LookupResult result; 3785 LookupResult result(GetIsolate());
3571 LocalLookupRealNamedProperty(name, &result); 3786 LocalLookupRealNamedProperty(name, &result);
3572 if (!result.IsProperty()) return GetHeap()->true_value(); 3787 if (!result.IsProperty()) return GetHeap()->true_value();
3573 3788
3574 // Normalize object if needed. 3789 // Normalize object if needed.
3575 Object* obj; 3790 Object* obj;
3576 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 3791 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
3577 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3792 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3578 } 3793 }
3579 3794
3580 return DeleteNormalizedProperty(name, mode); 3795 return DeleteNormalizedProperty(name, mode);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 Object* proto = GetPrototype(); 3924 Object* proto = GetPrototype();
3710 if (proto->IsNull()) return isolate->heap()->false_value(); 3925 if (proto->IsNull()) return isolate->heap()->false_value();
3711 ASSERT(proto->IsJSGlobalObject()); 3926 ASSERT(proto->IsJSGlobalObject());
3712 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); 3927 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode);
3713 } 3928 }
3714 3929
3715 uint32_t index = 0; 3930 uint32_t index = 0;
3716 if (name->AsArrayIndex(&index)) { 3931 if (name->AsArrayIndex(&index)) {
3717 return DeleteElement(index, mode); 3932 return DeleteElement(index, mode);
3718 } else { 3933 } else {
3719 LookupResult result; 3934 LookupResult result(isolate);
3720 LocalLookup(name, &result); 3935 LocalLookup(name, &result);
3721 if (!result.IsProperty()) return isolate->heap()->true_value(); 3936 if (!result.IsProperty()) return isolate->heap()->true_value();
3722 // Ignore attributes if forcing a deletion. 3937 // Ignore attributes if forcing a deletion.
3723 if (result.IsDontDelete() && mode != FORCE_DELETION) { 3938 if (result.IsDontDelete() && mode != FORCE_DELETION) {
3724 if (mode == STRICT_DELETION) { 3939 if (mode == STRICT_DELETION) {
3725 // Deleting a non-configurable property in strict mode. 3940 // Deleting a non-configurable property in strict mode.
3726 HandleScope scope(isolate); 3941 HandleScope scope(isolate);
3727 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; 3942 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) };
3728 return isolate->Throw(*isolate->factory()->NewTypeError( 3943 return isolate->Throw(*isolate->factory()->NewTypeError(
3729 "strict_delete_property", HandleVector(args, 2))); 3944 "strict_delete_property", HandleVector(args, 2)));
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3920 if (!maybe->To<Map>(&new_map)) return maybe; 4135 if (!maybe->To<Map>(&new_map)) return maybe;
3921 } 4136 }
3922 new_map->set_is_extensible(false); 4137 new_map->set_is_extensible(false);
3923 set_map(new_map); 4138 set_map(new_map);
3924 ASSERT(!map()->is_extensible()); 4139 ASSERT(!map()->is_extensible());
3925 return new_map; 4140 return new_map;
3926 } 4141 }
3927 4142
3928 4143
3929 // Tests for the fast common case for property enumeration: 4144 // Tests for the fast common case for property enumeration:
3930 // - This object and all prototypes has an enum cache (which means that it has 4145 // - This object and all prototypes has an enum cache (which means that
3931 // no interceptors and needs no access checks). 4146 // it is no proxy, has no interceptors and needs no access checks).
3932 // - This object has no elements. 4147 // - This object has no elements.
3933 // - No prototype has enumerable properties/elements. 4148 // - No prototype has enumerable properties/elements.
3934 bool JSObject::IsSimpleEnum() { 4149 bool JSReceiver::IsSimpleEnum() {
3935 Heap* heap = GetHeap(); 4150 Heap* heap = GetHeap();
3936 for (Object* o = this; 4151 for (Object* o = this;
3937 o != heap->null_value(); 4152 o != heap->null_value();
3938 o = JSObject::cast(o)->GetPrototype()) { 4153 o = JSObject::cast(o)->GetPrototype()) {
4154 if (!o->IsJSObject()) return false;
3939 JSObject* curr = JSObject::cast(o); 4155 JSObject* curr = JSObject::cast(o);
3940 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false; 4156 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false;
3941 ASSERT(!curr->HasNamedInterceptor()); 4157 ASSERT(!curr->HasNamedInterceptor());
3942 ASSERT(!curr->HasIndexedInterceptor()); 4158 ASSERT(!curr->HasIndexedInterceptor());
3943 ASSERT(!curr->IsAccessCheckNeeded()); 4159 ASSERT(!curr->IsAccessCheckNeeded());
3944 if (curr->NumberOfEnumElements() > 0) return false; 4160 if (curr->NumberOfEnumElements() > 0) return false;
3945 if (curr != this) { 4161 if (curr != this) {
3946 FixedArray* curr_fixed_array = 4162 FixedArray* curr_fixed_array =
3947 FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache()); 4163 FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache());
3948 if (curr_fixed_array->length() > 0) return false; 4164 if (curr_fixed_array->length() > 0) return false;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 for (Object* current = this; 4274 for (Object* current = this;
4059 current != heap->null_value() && current->IsJSObject(); 4275 current != heap->null_value() && current->IsJSObject();
4060 current = JSObject::cast(current)->GetPrototype()) { 4276 current = JSObject::cast(current)->GetPrototype()) {
4061 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); 4277 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
4062 if (result->IsProperty() && result->type() == CALLBACKS) return; 4278 if (result->IsProperty() && result->type() == CALLBACKS) return;
4063 } 4279 }
4064 result->NotFound(); 4280 result->NotFound();
4065 } 4281 }
4066 4282
4067 4283
4068 // Search for a getter or setter in an elements dictionary. Returns either 4284 // Search for a getter or setter in an elements dictionary and update its
4069 // undefined if the element is read-only, or the getter/setter pair (fixed 4285 // attributes. Returns either undefined if the element is read-only, or the
4070 // array) if there is an existing one, or the hole value if the element does 4286 // getter/setter pair (fixed array) if there is an existing one, or the hole
4071 // not exist or is a normal non-getter/setter data element. 4287 // value if the element does not exist or is a normal non-getter/setter data
4072 static Object* FindGetterSetterInDictionary(NumberDictionary* dictionary, 4288 // element.
4073 uint32_t index, 4289 static Object* UpdateGetterSetterInDictionary(NumberDictionary* dictionary,
4074 Heap* heap) { 4290 uint32_t index,
4291 PropertyAttributes attributes,
4292 Heap* heap) {
4075 int entry = dictionary->FindEntry(index); 4293 int entry = dictionary->FindEntry(index);
4076 if (entry != NumberDictionary::kNotFound) { 4294 if (entry != NumberDictionary::kNotFound) {
4077 Object* result = dictionary->ValueAt(entry); 4295 Object* result = dictionary->ValueAt(entry);
4078 PropertyDetails details = dictionary->DetailsAt(entry); 4296 PropertyDetails details = dictionary->DetailsAt(entry);
4079 if (details.IsReadOnly()) return heap->undefined_value(); 4297 if (details.IsReadOnly()) return heap->undefined_value();
4080 if (details.type() == CALLBACKS && result->IsFixedArray()) return result; 4298 if (details.type() == CALLBACKS && result->IsFixedArray()) {
4299 if (details.attributes() != attributes) {
4300 dictionary->DetailsAtPut(entry,
4301 PropertyDetails(attributes, CALLBACKS, index));
4302 }
4303 return result;
4304 }
4081 } 4305 }
4082 return heap->the_hole_value(); 4306 return heap->the_hole_value();
4083 } 4307 }
4084 4308
4085 4309
4086 MaybeObject* JSObject::DefineGetterSetter(String* name, 4310 MaybeObject* JSObject::DefineGetterSetter(String* name,
4087 PropertyAttributes attributes) { 4311 PropertyAttributes attributes) {
4088 Heap* heap = GetHeap(); 4312 Heap* heap = GetHeap();
4089 // Make sure that the top context does not change when doing callbacks or 4313 // Make sure that the top context does not change when doing callbacks or
4090 // interceptor calls. 4314 // interceptor calls.
(...skipping 21 matching lines...) Expand all
4112 case EXTERNAL_SHORT_ELEMENTS: 4336 case EXTERNAL_SHORT_ELEMENTS:
4113 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4337 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4114 case EXTERNAL_INT_ELEMENTS: 4338 case EXTERNAL_INT_ELEMENTS:
4115 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4339 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
4116 case EXTERNAL_FLOAT_ELEMENTS: 4340 case EXTERNAL_FLOAT_ELEMENTS:
4117 case EXTERNAL_DOUBLE_ELEMENTS: 4341 case EXTERNAL_DOUBLE_ELEMENTS:
4118 // Ignore getters and setters on pixel and external array 4342 // Ignore getters and setters on pixel and external array
4119 // elements. 4343 // elements.
4120 return heap->undefined_value(); 4344 return heap->undefined_value();
4121 case DICTIONARY_ELEMENTS: { 4345 case DICTIONARY_ELEMENTS: {
4122 Object* probe = 4346 Object* probe = UpdateGetterSetterInDictionary(element_dictionary(),
4123 FindGetterSetterInDictionary(element_dictionary(), index, heap); 4347 index,
4348 attributes,
4349 heap);
4124 if (!probe->IsTheHole()) return probe; 4350 if (!probe->IsTheHole()) return probe;
4125 // Otherwise allow to override it. 4351 // Otherwise allow to override it.
4126 break; 4352 break;
4127 } 4353 }
4128 case NON_STRICT_ARGUMENTS_ELEMENTS: { 4354 case NON_STRICT_ARGUMENTS_ELEMENTS: {
4129 // Ascertain whether we have read-only properties or an existing 4355 // Ascertain whether we have read-only properties or an existing
4130 // getter/setter pair in an arguments elements dictionary backing 4356 // getter/setter pair in an arguments elements dictionary backing
4131 // store. 4357 // store.
4132 FixedArray* parameter_map = FixedArray::cast(elements()); 4358 FixedArray* parameter_map = FixedArray::cast(elements());
4133 uint32_t length = parameter_map->length(); 4359 uint32_t length = parameter_map->length();
4134 Object* probe = 4360 Object* probe =
4135 index < (length - 2) ? parameter_map->get(index + 2) : NULL; 4361 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
4136 if (probe == NULL || probe->IsTheHole()) { 4362 if (probe == NULL || probe->IsTheHole()) {
4137 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 4363 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
4138 if (arguments->IsDictionary()) { 4364 if (arguments->IsDictionary()) {
4139 NumberDictionary* dictionary = NumberDictionary::cast(arguments); 4365 NumberDictionary* dictionary = NumberDictionary::cast(arguments);
4140 probe = FindGetterSetterInDictionary(dictionary, index, heap); 4366 probe = UpdateGetterSetterInDictionary(dictionary,
4367 index,
4368 attributes,
4369 heap);
4141 if (!probe->IsTheHole()) return probe; 4370 if (!probe->IsTheHole()) return probe;
4142 } 4371 }
4143 } 4372 }
4144 break; 4373 break;
4145 } 4374 }
4146 } 4375 }
4147 } else { 4376 } else {
4148 // Lookup the name. 4377 // Lookup the name.
4149 LookupResult result; 4378 LookupResult result(heap->isolate());
4150 LocalLookup(name, &result); 4379 LocalLookup(name, &result);
4151 if (result.IsProperty()) { 4380 if (result.IsProperty()) {
4152 if (result.IsReadOnly()) return heap->undefined_value(); 4381 if (result.IsReadOnly()) return heap->undefined_value();
4153 if (result.type() == CALLBACKS) { 4382 if (result.type() == CALLBACKS) {
4154 Object* obj = result.GetCallbackObject(); 4383 Object* obj = result.GetCallbackObject();
4155 // Need to preserve old getters/setters. 4384 // Need to preserve old getters/setters.
4156 if (obj->IsFixedArray()) { 4385 if (obj->IsFixedArray()) {
4157 // Use set to update attributes. 4386 // Use set to update attributes.
4158 return SetPropertyCallback(name, obj, attributes); 4387 return SetPropertyCallback(name, obj, attributes);
4159 } 4388 }
4160 } 4389 }
4161 } 4390 }
4162 } 4391 }
4163 4392
4164 // Allocate the fixed array to hold getter and setter. 4393 // Allocate the fixed array to hold getter and setter.
4165 Object* structure; 4394 Object* structure;
4166 { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED); 4395 { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED);
4167 if (!maybe_structure->ToObject(&structure)) return maybe_structure; 4396 if (!maybe_structure->ToObject(&structure)) return maybe_structure;
4168 } 4397 }
4169 4398
4170 if (is_element) { 4399 if (is_element) {
4171 return SetElementCallback(index, structure, attributes); 4400 return SetElementCallback(index, structure, attributes);
4172 } else { 4401 } else {
4173 return SetPropertyCallback(name, structure, attributes); 4402 return SetPropertyCallback(name, structure, attributes);
4174 } 4403 }
4175 } 4404 }
4176 4405
4177 4406
4178 bool JSObject::CanSetCallback(String* name) { 4407 bool JSObject::CanSetCallback(String* name) {
4179 ASSERT(!IsAccessCheckNeeded() 4408 ASSERT(!IsAccessCheckNeeded() ||
4180 || Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET)); 4409 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
4181 4410
4182 // Check if there is an API defined callback object which prohibits 4411 // Check if there is an API defined callback object which prohibits
4183 // callback overwriting in this object or it's prototype chain. 4412 // callback overwriting in this object or it's prototype chain.
4184 // This mechanism is needed for instance in a browser setting, where 4413 // This mechanism is needed for instance in a browser setting, where
4185 // certain accessors such as window.location should not be allowed 4414 // certain accessors such as window.location should not be allowed
4186 // to be overwritten because allowing overwriting could potentially 4415 // to be overwritten because allowing overwriting could potentially
4187 // cause security problems. 4416 // cause security problems.
4188 LookupResult callback_result; 4417 LookupResult callback_result(GetIsolate());
4189 LookupCallback(name, &callback_result); 4418 LookupCallback(name, &callback_result);
4190 if (callback_result.IsProperty()) { 4419 if (callback_result.IsProperty()) {
4191 Object* obj = callback_result.GetCallbackObject(); 4420 Object* obj = callback_result.GetCallbackObject();
4192 if (obj->IsAccessorInfo() && 4421 if (obj->IsAccessorInfo() &&
4193 AccessorInfo::cast(obj)->prohibits_overwriting()) { 4422 AccessorInfo::cast(obj)->prohibits_overwriting()) {
4194 return false; 4423 return false;
4195 } 4424 }
4196 } 4425 }
4197 4426
4198 return true; 4427 return true;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
4375 break; 4604 break;
4376 } 4605 }
4377 4606
4378 Object* ok; 4607 Object* ok;
4379 { MaybeObject* maybe_ok = 4608 { MaybeObject* maybe_ok =
4380 SetElementCallback(index, info, info->property_attributes()); 4609 SetElementCallback(index, info, info->property_attributes());
4381 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 4610 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
4382 } 4611 }
4383 } else { 4612 } else {
4384 // Lookup the name. 4613 // Lookup the name.
4385 LookupResult result; 4614 LookupResult result(isolate);
4386 LocalLookup(name, &result); 4615 LocalLookup(name, &result);
4387 // ES5 forbids turning a property into an accessor if it's not 4616 // ES5 forbids turning a property into an accessor if it's not
4388 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). 4617 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
4389 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { 4618 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
4390 return isolate->heap()->undefined_value(); 4619 return isolate->heap()->undefined_value();
4391 } 4620 }
4392 Object* ok; 4621 Object* ok;
4393 { MaybeObject* maybe_ok = 4622 { MaybeObject* maybe_ok =
4394 SetPropertyCallback(name, info, info->property_attributes()); 4623 SetPropertyCallback(name, info, info->property_attributes());
4395 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 4624 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4433 return FixedArray::cast(element)->get(accessor_index); 4662 return FixedArray::cast(element)->get(accessor_index);
4434 } 4663 }
4435 } 4664 }
4436 } 4665 }
4437 } 4666 }
4438 } 4667 }
4439 } else { 4668 } else {
4440 for (Object* obj = this; 4669 for (Object* obj = this;
4441 obj != heap->null_value(); 4670 obj != heap->null_value();
4442 obj = JSObject::cast(obj)->GetPrototype()) { 4671 obj = JSObject::cast(obj)->GetPrototype()) {
4443 LookupResult result; 4672 LookupResult result(heap->isolate());
4444 JSObject::cast(obj)->LocalLookup(name, &result); 4673 JSObject::cast(obj)->LocalLookup(name, &result);
4445 if (result.IsProperty()) { 4674 if (result.IsProperty()) {
4446 if (result.IsReadOnly()) return heap->undefined_value(); 4675 if (result.IsReadOnly()) return heap->undefined_value();
4447 if (result.type() == CALLBACKS) { 4676 if (result.type() == CALLBACKS) {
4448 Object* obj = result.GetCallbackObject(); 4677 Object* obj = result.GetCallbackObject();
4449 if (obj->IsFixedArray()) { 4678 if (obj->IsFixedArray()) {
4450 return FixedArray::cast(obj)->get(accessor_index); 4679 return FixedArray::cast(obj)->get(accessor_index);
4451 } 4680 }
4452 } 4681 }
4453 } 4682 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4541 Map::cast(result)->set_prototype(prototype()); 4770 Map::cast(result)->set_prototype(prototype());
4542 Map::cast(result)->set_constructor(constructor()); 4771 Map::cast(result)->set_constructor(constructor());
4543 4772
4544 Map::cast(result)->set_bit_field(bit_field()); 4773 Map::cast(result)->set_bit_field(bit_field());
4545 Map::cast(result)->set_bit_field2(bit_field2()); 4774 Map::cast(result)->set_bit_field2(bit_field2());
4546 Map::cast(result)->set_bit_field3(bit_field3()); 4775 Map::cast(result)->set_bit_field3(bit_field3());
4547 4776
4548 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP); 4777 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
4549 4778
4550 #ifdef DEBUG 4779 #ifdef DEBUG
4551 if (Map::cast(result)->is_shared()) { 4780 if (FLAG_verify_heap && Map::cast(result)->is_shared()) {
4552 Map::cast(result)->SharedMapVerify(); 4781 Map::cast(result)->SharedMapVerify();
4553 } 4782 }
4554 #endif 4783 #endif
4555 4784
4556 return result; 4785 return result;
4557 } 4786 }
4558 4787
4559 4788
4560 MaybeObject* Map::CopyDropTransitions() { 4789 MaybeObject* Map::CopyDropTransitions() {
4561 Object* new_map; 4790 Object* new_map;
4562 { MaybeObject* maybe_new_map = CopyDropDescriptors(); 4791 { MaybeObject* maybe_new_map = CopyDropDescriptors();
4563 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 4792 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
4564 } 4793 }
4565 Object* descriptors; 4794 Object* descriptors;
4566 { MaybeObject* maybe_descriptors = 4795 { MaybeObject* maybe_descriptors =
4567 instance_descriptors()->RemoveTransitions(); 4796 instance_descriptors()->RemoveTransitions();
4568 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; 4797 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
4569 } 4798 }
4570 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); 4799 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
4571 return new_map; 4800 return new_map;
4572 } 4801 }
4573 4802
4803 void Map::UpdateCodeCache(Handle<Map> map,
4804 Handle<String> name,
4805 Handle<Code> code) {
4806 Isolate* isolate = map->GetIsolate();
4807 CALL_HEAP_FUNCTION_VOID(isolate,
4808 map->UpdateCodeCache(*name, *code));
4809 }
4574 4810
4575 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { 4811 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) {
4576 // Allocate the code cache if not present. 4812 // Allocate the code cache if not present.
4577 if (code_cache()->IsFixedArray()) { 4813 if (code_cache()->IsFixedArray()) {
4578 Object* result; 4814 Object* result;
4579 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); 4815 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache();
4580 if (!maybe_result->ToObject(&result)) return maybe_result; 4816 if (!maybe_result->ToObject(&result)) return maybe_result;
4581 } 4817 }
4582 set_code_cache(result); 4818 set_code_cache(result);
4583 } 4819 }
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
4953 5189
4954 void CodeCacheHashTable::RemoveByIndex(int index) { 5190 void CodeCacheHashTable::RemoveByIndex(int index) {
4955 ASSERT(index >= 0); 5191 ASSERT(index >= 0);
4956 Heap* heap = GetHeap(); 5192 Heap* heap = GetHeap();
4957 set(EntryToIndex(index), heap->null_value()); 5193 set(EntryToIndex(index), heap->null_value());
4958 set(EntryToIndex(index) + 1, heap->null_value()); 5194 set(EntryToIndex(index) + 1, heap->null_value());
4959 ElementRemoved(); 5195 ElementRemoved();
4960 } 5196 }
4961 5197
4962 5198
4963 MaybeObject* PolymorphicCodeCache::Update(MapList* maps, 5199 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache,
5200 MapHandleList* maps,
5201 Code::Flags flags,
5202 Handle<Code> code) {
5203 Isolate* isolate = cache->GetIsolate();
5204 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code));
5205 }
5206
5207
5208 MaybeObject* PolymorphicCodeCache::Update(MapHandleList* maps,
4964 Code::Flags flags, 5209 Code::Flags flags,
4965 Code* code) { 5210 Code* code) {
4966 // Initialize cache if necessary. 5211 // Initialize cache if necessary.
4967 if (cache()->IsUndefined()) { 5212 if (cache()->IsUndefined()) {
4968 Object* result; 5213 Object* result;
4969 { MaybeObject* maybe_result = 5214 { MaybeObject* maybe_result =
4970 PolymorphicCodeCacheHashTable::Allocate( 5215 PolymorphicCodeCacheHashTable::Allocate(
4971 PolymorphicCodeCacheHashTable::kInitialSize); 5216 PolymorphicCodeCacheHashTable::kInitialSize);
4972 if (!maybe_result->ToObject(&result)) return maybe_result; 5217 if (!maybe_result->ToObject(&result)) return maybe_result;
4973 } 5218 }
4974 set_cache(result); 5219 set_cache(result);
4975 } else { 5220 } else {
4976 // This entry shouldn't be contained in the cache yet. 5221 // This entry shouldn't be contained in the cache yet.
4977 ASSERT(PolymorphicCodeCacheHashTable::cast(cache()) 5222 ASSERT(PolymorphicCodeCacheHashTable::cast(cache())
4978 ->Lookup(maps, flags)->IsUndefined()); 5223 ->Lookup(maps, flags)->IsUndefined());
4979 } 5224 }
4980 PolymorphicCodeCacheHashTable* hash_table = 5225 PolymorphicCodeCacheHashTable* hash_table =
4981 PolymorphicCodeCacheHashTable::cast(cache()); 5226 PolymorphicCodeCacheHashTable::cast(cache());
4982 Object* new_cache; 5227 Object* new_cache;
4983 { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code); 5228 { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code);
4984 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; 5229 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache;
4985 } 5230 }
4986 set_cache(new_cache); 5231 set_cache(new_cache);
4987 return this; 5232 return this;
4988 } 5233 }
4989 5234
4990 5235
4991 Object* PolymorphicCodeCache::Lookup(MapList* maps, Code::Flags flags) { 5236 Handle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps,
5237 Code::Flags flags) {
4992 if (!cache()->IsUndefined()) { 5238 if (!cache()->IsUndefined()) {
4993 PolymorphicCodeCacheHashTable* hash_table = 5239 PolymorphicCodeCacheHashTable* hash_table =
4994 PolymorphicCodeCacheHashTable::cast(cache()); 5240 PolymorphicCodeCacheHashTable::cast(cache());
4995 return hash_table->Lookup(maps, flags); 5241 return Handle<Object>(hash_table->Lookup(maps, flags));
4996 } else { 5242 } else {
4997 return GetHeap()->undefined_value(); 5243 return GetIsolate()->factory()->undefined_value();
4998 } 5244 }
4999 } 5245 }
5000 5246
5001 5247
5002 // Despite their name, object of this class are not stored in the actual 5248 // Despite their name, object of this class are not stored in the actual
5003 // hash table; instead they're temporarily used for lookups. It is therefore 5249 // hash table; instead they're temporarily used for lookups. It is therefore
5004 // safe to have a weak (non-owning) pointer to a MapList as a member field. 5250 // safe to have a weak (non-owning) pointer to a MapList as a member field.
5005 class PolymorphicCodeCacheHashTableKey : public HashTableKey { 5251 class PolymorphicCodeCacheHashTableKey : public HashTableKey {
5006 public: 5252 public:
5007 // Callers must ensure that |maps| outlives the newly constructed object. 5253 // Callers must ensure that |maps| outlives the newly constructed object.
5008 PolymorphicCodeCacheHashTableKey(MapList* maps, int code_flags) 5254 PolymorphicCodeCacheHashTableKey(MapHandleList* maps, int code_flags)
5009 : maps_(maps), 5255 : maps_(maps),
5010 code_flags_(code_flags) {} 5256 code_flags_(code_flags) {}
5011 5257
5012 bool IsMatch(Object* other) { 5258 bool IsMatch(Object* other) {
5013 MapList other_maps(kDefaultListAllocationSize); 5259 MapHandleList other_maps(kDefaultListAllocationSize);
5014 int other_flags; 5260 int other_flags;
5015 FromObject(other, &other_flags, &other_maps); 5261 FromObject(other, &other_flags, &other_maps);
5016 if (code_flags_ != other_flags) return false; 5262 if (code_flags_ != other_flags) return false;
5017 if (maps_->length() != other_maps.length()) return false; 5263 if (maps_->length() != other_maps.length()) return false;
5018 // Compare just the hashes first because it's faster. 5264 // Compare just the hashes first because it's faster.
5019 int this_hash = MapsHashHelper(maps_, code_flags_); 5265 int this_hash = MapsHashHelper(maps_, code_flags_);
5020 int other_hash = MapsHashHelper(&other_maps, other_flags); 5266 int other_hash = MapsHashHelper(&other_maps, other_flags);
5021 if (this_hash != other_hash) return false; 5267 if (this_hash != other_hash) return false;
5022 5268
5023 // Full comparison: for each map in maps_, look for an equivalent map in 5269 // Full comparison: for each map in maps_, look for an equivalent map in
5024 // other_maps. This implementation is slow, but probably good enough for 5270 // other_maps. This implementation is slow, but probably good enough for
5025 // now because the lists are short (<= 4 elements currently). 5271 // now because the lists are short (<= 4 elements currently).
5026 for (int i = 0; i < maps_->length(); ++i) { 5272 for (int i = 0; i < maps_->length(); ++i) {
5027 bool match_found = false; 5273 bool match_found = false;
5028 for (int j = 0; j < other_maps.length(); ++j) { 5274 for (int j = 0; j < other_maps.length(); ++j) {
5029 if (maps_->at(i)->EquivalentTo(other_maps.at(j))) { 5275 if (maps_->at(i)->EquivalentTo(*other_maps.at(j))) {
5030 match_found = true; 5276 match_found = true;
5031 break; 5277 break;
5032 } 5278 }
5033 } 5279 }
5034 if (!match_found) return false; 5280 if (!match_found) return false;
5035 } 5281 }
5036 return true; 5282 return true;
5037 } 5283 }
5038 5284
5039 static uint32_t MapsHashHelper(MapList* maps, int code_flags) { 5285 static uint32_t MapsHashHelper(MapHandleList* maps, int code_flags) {
5040 uint32_t hash = code_flags; 5286 uint32_t hash = code_flags;
5041 for (int i = 0; i < maps->length(); ++i) { 5287 for (int i = 0; i < maps->length(); ++i) {
5042 hash ^= maps->at(i)->Hash(); 5288 hash ^= maps->at(i)->Hash();
5043 } 5289 }
5044 return hash; 5290 return hash;
5045 } 5291 }
5046 5292
5047 uint32_t Hash() { 5293 uint32_t Hash() {
5048 return MapsHashHelper(maps_, code_flags_); 5294 return MapsHashHelper(maps_, code_flags_);
5049 } 5295 }
5050 5296
5051 uint32_t HashForObject(Object* obj) { 5297 uint32_t HashForObject(Object* obj) {
5052 MapList other_maps(kDefaultListAllocationSize); 5298 MapHandleList other_maps(kDefaultListAllocationSize);
5053 int other_flags; 5299 int other_flags;
5054 FromObject(obj, &other_flags, &other_maps); 5300 FromObject(obj, &other_flags, &other_maps);
5055 return MapsHashHelper(&other_maps, other_flags); 5301 return MapsHashHelper(&other_maps, other_flags);
5056 } 5302 }
5057 5303
5058 MUST_USE_RESULT MaybeObject* AsObject() { 5304 MUST_USE_RESULT MaybeObject* AsObject() {
5059 Object* obj; 5305 Object* obj;
5060 // The maps in |maps_| must be copied to a newly allocated FixedArray, 5306 // The maps in |maps_| must be copied to a newly allocated FixedArray,
5061 // both because the referenced MapList is short-lived, and because C++ 5307 // both because the referenced MapList is short-lived, and because C++
5062 // objects can't be stored in the heap anyway. 5308 // objects can't be stored in the heap anyway.
5063 { MaybeObject* maybe_obj = 5309 { MaybeObject* maybe_obj =
5064 HEAP->AllocateUninitializedFixedArray(maps_->length() + 1); 5310 HEAP->AllocateUninitializedFixedArray(maps_->length() + 1);
5065 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 5311 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5066 } 5312 }
5067 FixedArray* list = FixedArray::cast(obj); 5313 FixedArray* list = FixedArray::cast(obj);
5068 list->set(0, Smi::FromInt(code_flags_)); 5314 list->set(0, Smi::FromInt(code_flags_));
5069 for (int i = 0; i < maps_->length(); ++i) { 5315 for (int i = 0; i < maps_->length(); ++i) {
5070 list->set(i + 1, maps_->at(i)); 5316 list->set(i + 1, *maps_->at(i));
5071 } 5317 }
5072 return list; 5318 return list;
5073 } 5319 }
5074 5320
5075 private: 5321 private:
5076 static MapList* FromObject(Object* obj, int* code_flags, MapList* maps) { 5322 static MapHandleList* FromObject(Object* obj,
5323 int* code_flags,
5324 MapHandleList* maps) {
5077 FixedArray* list = FixedArray::cast(obj); 5325 FixedArray* list = FixedArray::cast(obj);
5078 maps->Rewind(0); 5326 maps->Rewind(0);
5079 *code_flags = Smi::cast(list->get(0))->value(); 5327 *code_flags = Smi::cast(list->get(0))->value();
5080 for (int i = 1; i < list->length(); ++i) { 5328 for (int i = 1; i < list->length(); ++i) {
5081 maps->Add(Map::cast(list->get(i))); 5329 maps->Add(Handle<Map>(Map::cast(list->get(i))));
5082 } 5330 }
5083 return maps; 5331 return maps;
5084 } 5332 }
5085 5333
5086 MapList* maps_; // weak. 5334 MapHandleList* maps_; // weak.
5087 int code_flags_; 5335 int code_flags_;
5088 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; 5336 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1;
5089 }; 5337 };
5090 5338
5091 5339
5092 Object* PolymorphicCodeCacheHashTable::Lookup(MapList* maps, int code_flags) { 5340 Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps,
5341 int code_flags) {
5093 PolymorphicCodeCacheHashTableKey key(maps, code_flags); 5342 PolymorphicCodeCacheHashTableKey key(maps, code_flags);
5094 int entry = FindEntry(&key); 5343 int entry = FindEntry(&key);
5095 if (entry == kNotFound) return GetHeap()->undefined_value(); 5344 if (entry == kNotFound) return GetHeap()->undefined_value();
5096 return get(EntryToIndex(entry) + 1); 5345 return get(EntryToIndex(entry) + 1);
5097 } 5346 }
5098 5347
5099 5348
5100 MaybeObject* PolymorphicCodeCacheHashTable::Put(MapList* maps, 5349 MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps,
5101 int code_flags, 5350 int code_flags,
5102 Code* code) { 5351 Code* code) {
5103 PolymorphicCodeCacheHashTableKey key(maps, code_flags); 5352 PolymorphicCodeCacheHashTableKey key(maps, code_flags);
5104 Object* obj; 5353 Object* obj;
5105 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 5354 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
5106 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 5355 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5107 } 5356 }
5108 PolymorphicCodeCacheHashTable* cache = 5357 PolymorphicCodeCacheHashTable* cache =
5109 reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj); 5358 reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj);
5110 int entry = cache->FindInsertionEntry(key.Hash()); 5359 int entry = cache->FindInsertionEntry(key.Hash());
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
5225 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 5474 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
5226 FixedArray* new_cache) { 5475 FixedArray* new_cache) {
5227 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); 5476 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
5228 if (HasEnumCache()) { 5477 if (HasEnumCache()) {
5229 FixedArray::cast(get(kEnumerationIndexIndex))-> 5478 FixedArray::cast(get(kEnumerationIndexIndex))->
5230 set(kEnumCacheBridgeCacheIndex, new_cache); 5479 set(kEnumCacheBridgeCacheIndex, new_cache);
5231 } else { 5480 } else {
5232 if (IsEmpty()) return; // Do nothing for empty descriptor array. 5481 if (IsEmpty()) return; // Do nothing for empty descriptor array.
5233 FixedArray::cast(bridge_storage)-> 5482 FixedArray::cast(bridge_storage)->
5234 set(kEnumCacheBridgeCacheIndex, new_cache); 5483 set(kEnumCacheBridgeCacheIndex, new_cache);
5235 fast_set(FixedArray::cast(bridge_storage), 5484 NoWriteBarrierSet(FixedArray::cast(bridge_storage),
5236 kEnumCacheBridgeEnumIndex, 5485 kEnumCacheBridgeEnumIndex,
5237 get(kEnumerationIndexIndex)); 5486 get(kEnumerationIndexIndex));
5238 set(kEnumerationIndexIndex, bridge_storage); 5487 set(kEnumerationIndexIndex, bridge_storage);
5239 } 5488 }
5240 } 5489 }
5241 5490
5242 5491
5243 MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor, 5492 MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor,
5244 TransitionFlag transition_flag) { 5493 TransitionFlag transition_flag) {
5245 // Transitions are only kept when inserting another transition. 5494 // Transitions are only kept when inserting another transition.
5246 // This precondition is not required by this function's implementation, but 5495 // This precondition is not required by this function's implementation, but
5247 // is currently required by the semantics of maps, so we check it. 5496 // is currently required by the semantics of maps, so we check it.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
5288 t == FIELD || 5537 t == FIELD ||
5289 t == CALLBACKS || 5538 t == CALLBACKS ||
5290 t == INTERCEPTOR) { 5539 t == INTERCEPTOR) {
5291 keep_enumeration_index = true; 5540 keep_enumeration_index = true;
5292 } else if (remove_transitions) { 5541 } else if (remove_transitions) {
5293 // Replaced descriptor has been counted as removed if it is 5542 // Replaced descriptor has been counted as removed if it is
5294 // a transition that will be replaced. Adjust count in this case. 5543 // a transition that will be replaced. Adjust count in this case.
5295 ++new_size; 5544 ++new_size;
5296 } 5545 }
5297 } 5546 }
5547
5548 DescriptorArray* new_descriptors;
5298 { MaybeObject* maybe_result = Allocate(new_size); 5549 { MaybeObject* maybe_result = Allocate(new_size);
5299 if (!maybe_result->ToObject(&result)) return maybe_result; 5550 if (!maybe_result->To<DescriptorArray>(&new_descriptors)) {
5551 return maybe_result;
5552 }
5300 } 5553 }
5301 DescriptorArray* new_descriptors = DescriptorArray::cast(result); 5554
5555 DescriptorArray::WhitenessWitness witness(new_descriptors);
5556
5302 // Set the enumeration index in the descriptors and set the enumeration index 5557 // Set the enumeration index in the descriptors and set the enumeration index
5303 // in the result. 5558 // in the result.
5304 int enumeration_index = NextEnumerationIndex(); 5559 int enumeration_index = NextEnumerationIndex();
5305 if (!descriptor->GetDetails().IsTransition()) { 5560 if (!descriptor->GetDetails().IsTransition()) {
5306 if (keep_enumeration_index) { 5561 if (keep_enumeration_index) {
5307 descriptor->SetEnumerationIndex( 5562 descriptor->SetEnumerationIndex(
5308 PropertyDetails(GetDetails(index)).index()); 5563 PropertyDetails(GetDetails(index)).index());
5309 } else { 5564 } else {
5310 descriptor->SetEnumerationIndex(enumeration_index); 5565 descriptor->SetEnumerationIndex(enumeration_index);
5311 ++enumeration_index; 5566 ++enumeration_index;
5312 } 5567 }
5313 } 5568 }
5314 new_descriptors->SetNextEnumerationIndex(enumeration_index); 5569 new_descriptors->SetNextEnumerationIndex(enumeration_index);
5315 5570
5316 // Copy the descriptors, filtering out transitions and null descriptors, 5571 // Copy the descriptors, filtering out transitions and null descriptors,
5317 // and inserting or replacing a descriptor. 5572 // and inserting or replacing a descriptor.
5318 uint32_t descriptor_hash = descriptor->GetKey()->Hash(); 5573 uint32_t descriptor_hash = descriptor->GetKey()->Hash();
5319 int from_index = 0; 5574 int from_index = 0;
5320 int to_index = 0; 5575 int to_index = 0;
5321 5576
5322 for (; from_index < number_of_descriptors(); from_index++) { 5577 for (; from_index < number_of_descriptors(); from_index++) {
5323 String* key = GetKey(from_index); 5578 String* key = GetKey(from_index);
5324 if (key->Hash() > descriptor_hash || key == descriptor->GetKey()) { 5579 if (key->Hash() > descriptor_hash || key == descriptor->GetKey()) {
5325 break; 5580 break;
5326 } 5581 }
5327 if (IsNullDescriptor(from_index)) continue; 5582 if (IsNullDescriptor(from_index)) continue;
5328 if (remove_transitions && IsTransition(from_index)) continue; 5583 if (remove_transitions && IsTransition(from_index)) continue;
5329 new_descriptors->CopyFrom(to_index++, this, from_index); 5584 new_descriptors->CopyFrom(to_index++, this, from_index, witness);
5330 } 5585 }
5331 5586
5332 new_descriptors->Set(to_index++, descriptor); 5587 new_descriptors->Set(to_index++, descriptor, witness);
5333 if (replacing) from_index++; 5588 if (replacing) from_index++;
5334 5589
5335 for (; from_index < number_of_descriptors(); from_index++) { 5590 for (; from_index < number_of_descriptors(); from_index++) {
5336 if (IsNullDescriptor(from_index)) continue; 5591 if (IsNullDescriptor(from_index)) continue;
5337 if (remove_transitions && IsTransition(from_index)) continue; 5592 if (remove_transitions && IsTransition(from_index)) continue;
5338 new_descriptors->CopyFrom(to_index++, this, from_index); 5593 new_descriptors->CopyFrom(to_index++, this, from_index, witness);
5339 } 5594 }
5340 5595
5341 ASSERT(to_index == new_descriptors->number_of_descriptors()); 5596 ASSERT(to_index == new_descriptors->number_of_descriptors());
5342 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); 5597 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
5343 5598
5344 return new_descriptors; 5599 return new_descriptors;
5345 } 5600 }
5346 5601
5347 5602
5348 MaybeObject* DescriptorArray::RemoveTransitions() { 5603 MaybeObject* DescriptorArray::RemoveTransitions() {
5349 // Remove all transitions and null descriptors. Return a copy of the array 5604 // Remove all transitions and null descriptors. Return a copy of the array
5350 // with all transitions removed, or a Failure object if the new array could 5605 // with all transitions removed, or a Failure object if the new array could
5351 // not be allocated. 5606 // not be allocated.
5352 5607
5353 // Compute the size of the map transition entries to be removed. 5608 // Compute the size of the map transition entries to be removed.
5354 int num_removed = 0; 5609 int num_removed = 0;
5355 for (int i = 0; i < number_of_descriptors(); i++) { 5610 for (int i = 0; i < number_of_descriptors(); i++) {
5356 if (!IsProperty(i)) num_removed++; 5611 if (!IsProperty(i)) num_removed++;
5357 } 5612 }
5358 5613
5359 // Allocate the new descriptor array. 5614 // Allocate the new descriptor array.
5360 Object* result; 5615 DescriptorArray* new_descriptors;
5361 { MaybeObject* maybe_result = Allocate(number_of_descriptors() - num_removed); 5616 { MaybeObject* maybe_result = Allocate(number_of_descriptors() - num_removed);
5362 if (!maybe_result->ToObject(&result)) return maybe_result; 5617 if (!maybe_result->To<DescriptorArray>(&new_descriptors)) {
5618 return maybe_result;
5619 }
5363 } 5620 }
5364 DescriptorArray* new_descriptors = DescriptorArray::cast(result); 5621
5622 DescriptorArray::WhitenessWitness witness(new_descriptors);
5365 5623
5366 // Copy the content. 5624 // Copy the content.
5367 int next_descriptor = 0; 5625 int next_descriptor = 0;
5368 for (int i = 0; i < number_of_descriptors(); i++) { 5626 for (int i = 0; i < number_of_descriptors(); i++) {
5369 if (IsProperty(i)) new_descriptors->CopyFrom(next_descriptor++, this, i); 5627 if (IsProperty(i)) {
5628 new_descriptors->CopyFrom(next_descriptor++, this, i, witness);
5629 }
5370 } 5630 }
5371 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); 5631 ASSERT(next_descriptor == new_descriptors->number_of_descriptors());
5372 5632
5373 return new_descriptors; 5633 return new_descriptors;
5374 } 5634 }
5375 5635
5376 5636
5377 void DescriptorArray::SortUnchecked() { 5637 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
5378 // In-place heap sort. 5638 // In-place heap sort.
5379 int len = number_of_descriptors(); 5639 int len = number_of_descriptors();
5380 5640
5381 // Bottom-up max-heap construction. 5641 // Bottom-up max-heap construction.
5382 // Index of the last node with children 5642 // Index of the last node with children
5383 const int max_parent_index = (len / 2) - 1; 5643 const int max_parent_index = (len / 2) - 1;
5384 for (int i = max_parent_index; i >= 0; --i) { 5644 for (int i = max_parent_index; i >= 0; --i) {
5385 int parent_index = i; 5645 int parent_index = i;
5386 const uint32_t parent_hash = GetKey(i)->Hash(); 5646 const uint32_t parent_hash = GetKey(i)->Hash();
5387 while (parent_index <= max_parent_index) { 5647 while (parent_index <= max_parent_index) {
5388 int child_index = 2 * parent_index + 1; 5648 int child_index = 2 * parent_index + 1;
5389 uint32_t child_hash = GetKey(child_index)->Hash(); 5649 uint32_t child_hash = GetKey(child_index)->Hash();
5390 if (child_index + 1 < len) { 5650 if (child_index + 1 < len) {
5391 uint32_t right_child_hash = GetKey(child_index + 1)->Hash(); 5651 uint32_t right_child_hash = GetKey(child_index + 1)->Hash();
5392 if (right_child_hash > child_hash) { 5652 if (right_child_hash > child_hash) {
5393 child_index++; 5653 child_index++;
5394 child_hash = right_child_hash; 5654 child_hash = right_child_hash;
5395 } 5655 }
5396 } 5656 }
5397 if (child_hash <= parent_hash) break; 5657 if (child_hash <= parent_hash) break;
5398 Swap(parent_index, child_index); 5658 NoWriteBarrierSwapDescriptors(parent_index, child_index);
5399 // Now element at child_index could be < its children. 5659 // Now element at child_index could be < its children.
5400 parent_index = child_index; // parent_hash remains correct. 5660 parent_index = child_index; // parent_hash remains correct.
5401 } 5661 }
5402 } 5662 }
5403 5663
5404 // Extract elements and create sorted array. 5664 // Extract elements and create sorted array.
5405 for (int i = len - 1; i > 0; --i) { 5665 for (int i = len - 1; i > 0; --i) {
5406 // Put max element at the back of the array. 5666 // Put max element at the back of the array.
5407 Swap(0, i); 5667 NoWriteBarrierSwapDescriptors(0, i);
5408 // Sift down the new top element. 5668 // Shift down the new top element.
5409 int parent_index = 0; 5669 int parent_index = 0;
5410 const uint32_t parent_hash = GetKey(parent_index)->Hash(); 5670 const uint32_t parent_hash = GetKey(parent_index)->Hash();
5411 const int max_parent_index = (i / 2) - 1; 5671 const int max_parent_index = (i / 2) - 1;
5412 while (parent_index <= max_parent_index) { 5672 while (parent_index <= max_parent_index) {
5413 int child_index = parent_index * 2 + 1; 5673 int child_index = parent_index * 2 + 1;
5414 uint32_t child_hash = GetKey(child_index)->Hash(); 5674 uint32_t child_hash = GetKey(child_index)->Hash();
5415 if (child_index + 1 < i) { 5675 if (child_index + 1 < i) {
5416 uint32_t right_child_hash = GetKey(child_index + 1)->Hash(); 5676 uint32_t right_child_hash = GetKey(child_index + 1)->Hash();
5417 if (right_child_hash > child_hash) { 5677 if (right_child_hash > child_hash) {
5418 child_index++; 5678 child_index++;
5419 child_hash = right_child_hash; 5679 child_hash = right_child_hash;
5420 } 5680 }
5421 } 5681 }
5422 if (child_hash <= parent_hash) break; 5682 if (child_hash <= parent_hash) break;
5423 Swap(parent_index, child_index); 5683 NoWriteBarrierSwapDescriptors(parent_index, child_index);
5424 parent_index = child_index; 5684 parent_index = child_index;
5425 } 5685 }
5426 } 5686 }
5427 } 5687 }
5428 5688
5429 5689
5430 void DescriptorArray::Sort() { 5690 void DescriptorArray::Sort(const WhitenessWitness& witness) {
5431 SortUnchecked(); 5691 SortUnchecked(witness);
5432 SLOW_ASSERT(IsSortedNoDuplicates()); 5692 SLOW_ASSERT(IsSortedNoDuplicates());
5433 } 5693 }
5434 5694
5435 5695
5436 int DescriptorArray::BinarySearch(String* name, int low, int high) { 5696 int DescriptorArray::BinarySearch(String* name, int low, int high) {
5437 uint32_t hash = name->Hash(); 5697 uint32_t hash = name->Hash();
5438 5698
5439 while (low <= high) { 5699 while (low <= high) {
5440 int mid = (low + high) / 2; 5700 int mid = (low + high) / 2;
5441 String* mid_name = GetKey(mid); 5701 String* mid_name = GetKey(mid);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
5506 } 5766 }
5507 #endif 5767 #endif
5508 5768
5509 5769
5510 bool String::LooksValid() { 5770 bool String::LooksValid() {
5511 if (!Isolate::Current()->heap()->Contains(this)) return false; 5771 if (!Isolate::Current()->heap()->Contains(this)) return false;
5512 return true; 5772 return true;
5513 } 5773 }
5514 5774
5515 5775
5516 int String::Utf8Length() {
5517 if (IsAsciiRepresentation()) return length();
5518 // Attempt to flatten before accessing the string. It probably
5519 // doesn't make Utf8Length faster, but it is very likely that
5520 // the string will be accessed later (for example by WriteUtf8)
5521 // so it's still a good idea.
5522 Heap* heap = GetHeap();
5523 TryFlatten();
5524 Access<StringInputBuffer> buffer(
5525 heap->isolate()->objects_string_input_buffer());
5526 buffer->Reset(0, this);
5527 int result = 0;
5528 while (buffer->has_more())
5529 result += unibrow::Utf8::Length(buffer->GetNext());
5530 return result;
5531 }
5532
5533
5534 String::FlatContent String::GetFlatContent() { 5776 String::FlatContent String::GetFlatContent() {
5535 int length = this->length(); 5777 int length = this->length();
5536 StringShape shape(this); 5778 StringShape shape(this);
5537 String* string = this; 5779 String* string = this;
5538 int offset = 0; 5780 int offset = 0;
5539 if (shape.representation_tag() == kConsStringTag) { 5781 if (shape.representation_tag() == kConsStringTag) {
5540 ConsString* cons = ConsString::cast(string); 5782 ConsString* cons = ConsString::cast(string);
5541 if (cons->second()->length() != 0) { 5783 if (cons->second()->length() != 0) {
5542 return FlatContent(); 5784 return FlatContent();
5543 } 5785 }
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5947 max_chars); 6189 max_chars);
5948 default: 6190 default:
5949 break; 6191 break;
5950 } 6192 }
5951 6193
5952 UNREACHABLE(); 6194 UNREACHABLE();
5953 return 0; 6195 return 0;
5954 } 6196 }
5955 6197
5956 6198
6199 // This method determines the type of string involved and then gets the UTF8
6200 // length of the string. It doesn't flatten the string and has log(n) recursion
6201 // for a string of length n.
6202 int String::Utf8Length(String* input, int from, int to) {
6203 if (from == to) return 0;
6204 int total = 0;
6205 while (true) {
6206 if (input->IsAsciiRepresentation()) return total + to - from;
6207 switch (StringShape(input).representation_tag()) {
6208 case kConsStringTag: {
6209 ConsString* str = ConsString::cast(input);
6210 String* first = str->first();
6211 String* second = str->second();
6212 int first_length = first->length();
6213 if (first_length - from < to - first_length) {
6214 if (first_length > from) {
6215 // Left hand side is shorter.
6216 total += Utf8Length(first, from, first_length);
6217 input = second;
6218 from = 0;
6219 to -= first_length;
6220 } else {
6221 // We only need the right hand side.
6222 input = second;
6223 from -= first_length;
6224 to -= first_length;
6225 }
6226 } else {
6227 if (first_length <= to) {
6228 // Right hand side is shorter.
6229 total += Utf8Length(second, 0, to - first_length);
6230 input = first;
6231 to = first_length;
6232 } else {
6233 // We only need the left hand side.
6234 input = first;
6235 }
6236 }
6237 continue;
6238 }
6239 case kExternalStringTag:
6240 case kSeqStringTag: {
6241 Vector<const uc16> vector = input->GetFlatContent().ToUC16Vector();
6242 const uc16* p = vector.start();
6243 for (int i = from; i < to; i++) {
6244 total += unibrow::Utf8::Length(p[i]);
6245 }
6246 return total;
6247 }
6248 case kSlicedStringTag: {
6249 SlicedString* str = SlicedString::cast(input);
6250 int offset = str->offset();
6251 input = str->parent();
6252 from += offset;
6253 to += offset;
6254 continue;
6255 }
6256 default:
6257 break;
6258 }
6259 UNREACHABLE();
6260 return 0;
6261 }
6262 return 0;
6263 }
6264
6265
5957 void Relocatable::PostGarbageCollectionProcessing() { 6266 void Relocatable::PostGarbageCollectionProcessing() {
5958 Isolate* isolate = Isolate::Current(); 6267 Isolate* isolate = Isolate::Current();
5959 Relocatable* current = isolate->relocatable_top(); 6268 Relocatable* current = isolate->relocatable_top();
5960 while (current != NULL) { 6269 while (current != NULL) {
5961 current->PostGarbageCollection(); 6270 current->PostGarbageCollection();
5962 current = current->prev_; 6271 current = current->prev_;
5963 } 6272 }
5964 } 6273 }
5965 6274
5966 6275
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
6844 7153
6845 void JSFunction::MarkForLazyRecompilation() { 7154 void JSFunction::MarkForLazyRecompilation() {
6846 ASSERT(is_compiled() && !IsOptimized()); 7155 ASSERT(is_compiled() && !IsOptimized());
6847 ASSERT(shared()->allows_lazy_compilation() || 7156 ASSERT(shared()->allows_lazy_compilation() ||
6848 code()->optimizable()); 7157 code()->optimizable());
6849 Builtins* builtins = GetIsolate()->builtins(); 7158 Builtins* builtins = GetIsolate()->builtins();
6850 ReplaceCode(builtins->builtin(Builtins::kLazyRecompile)); 7159 ReplaceCode(builtins->builtin(Builtins::kLazyRecompile));
6851 } 7160 }
6852 7161
6853 7162
7163 bool SharedFunctionInfo::EnsureCompiled(Handle<SharedFunctionInfo> shared,
7164 ClearExceptionFlag flag) {
7165 return shared->is_compiled() || CompileLazy(shared, flag);
7166 }
7167
7168
7169 static bool CompileLazyHelper(CompilationInfo* info,
7170 ClearExceptionFlag flag) {
7171 // Compile the source information to a code object.
7172 ASSERT(info->IsOptimizing() || !info->shared_info()->is_compiled());
7173 ASSERT(!info->isolate()->has_pending_exception());
7174 bool result = Compiler::CompileLazy(info);
7175 ASSERT(result != Isolate::Current()->has_pending_exception());
7176 if (!result && flag == CLEAR_EXCEPTION) {
7177 info->isolate()->clear_pending_exception();
7178 }
7179 return result;
7180 }
7181
7182
7183 bool SharedFunctionInfo::CompileLazy(Handle<SharedFunctionInfo> shared,
7184 ClearExceptionFlag flag) {
7185 CompilationInfo info(shared);
7186 return CompileLazyHelper(&info, flag);
7187 }
7188
7189
7190 bool JSFunction::CompileLazy(Handle<JSFunction> function,
7191 ClearExceptionFlag flag) {
7192 bool result = true;
7193 if (function->shared()->is_compiled()) {
7194 function->ReplaceCode(function->shared()->code());
7195 function->shared()->set_code_age(0);
7196 } else {
7197 CompilationInfo info(function);
7198 result = CompileLazyHelper(&info, flag);
7199 ASSERT(!result || function->is_compiled());
7200 }
7201 return result;
7202 }
7203
7204
7205 bool JSFunction::CompileOptimized(Handle<JSFunction> function,
7206 int osr_ast_id,
7207 ClearExceptionFlag flag) {
7208 CompilationInfo info(function);
7209 info.SetOptimizing(osr_ast_id);
7210 return CompileLazyHelper(&info, flag);
7211 }
7212
7213
6854 bool JSFunction::IsInlineable() { 7214 bool JSFunction::IsInlineable() {
6855 if (IsBuiltin()) return false; 7215 if (IsBuiltin()) return false;
6856 SharedFunctionInfo* shared_info = shared(); 7216 SharedFunctionInfo* shared_info = shared();
6857 // Check that the function has a script associated with it. 7217 // Check that the function has a script associated with it.
6858 if (!shared_info->script()->IsScript()) return false; 7218 if (!shared_info->script()->IsScript()) return false;
6859 if (shared_info->optimization_disabled()) return false; 7219 if (shared_info->optimization_disabled()) return false;
6860 Code* code = shared_info->code(); 7220 Code* code = shared_info->code();
6861 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; 7221 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true;
6862 // If we never ran this (unlikely) then lets try to optimize it. 7222 // If we never ran this (unlikely) then lets try to optimize it.
6863 if (code->kind() != Code::FUNCTION) return true; 7223 if (code->kind() != Code::FUNCTION) return true;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
7026 7386
7027 Heap* heap = GetHeap(); 7387 Heap* heap = GetHeap();
7028 7388
7029 // Traverse the proposed prototype chain looking for setters for properties of 7389 // Traverse the proposed prototype chain looking for setters for properties of
7030 // the same names as are set by the inline constructor. 7390 // the same names as are set by the inline constructor.
7031 for (Object* obj = prototype; 7391 for (Object* obj = prototype;
7032 obj != heap->null_value(); 7392 obj != heap->null_value();
7033 obj = obj->GetPrototype()) { 7393 obj = obj->GetPrototype()) {
7034 JSObject* js_object = JSObject::cast(obj); 7394 JSObject* js_object = JSObject::cast(obj);
7035 for (int i = 0; i < this_property_assignments_count(); i++) { 7395 for (int i = 0; i < this_property_assignments_count(); i++) {
7036 LookupResult result; 7396 LookupResult result(heap->isolate());
7037 String* name = GetThisPropertyAssignmentName(i); 7397 String* name = GetThisPropertyAssignmentName(i);
7038 js_object->LocalLookupRealNamedProperty(name, &result); 7398 js_object->LocalLookupRealNamedProperty(name, &result);
7039 if (result.IsProperty() && result.type() == CALLBACKS) { 7399 if (result.IsProperty() && result.type() == CALLBACKS) {
7040 return false; 7400 return false;
7041 } 7401 }
7042 } 7402 }
7043 } 7403 }
7044 7404
7045 return true; 7405 return true;
7046 } 7406 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
7384 7744
7385 void Code::Relocate(intptr_t delta) { 7745 void Code::Relocate(intptr_t delta) {
7386 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { 7746 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
7387 it.rinfo()->apply(delta); 7747 it.rinfo()->apply(delta);
7388 } 7748 }
7389 CPU::FlushICache(instruction_start(), instruction_size()); 7749 CPU::FlushICache(instruction_start(), instruction_size());
7390 } 7750 }
7391 7751
7392 7752
7393 void Code::CopyFrom(const CodeDesc& desc) { 7753 void Code::CopyFrom(const CodeDesc& desc) {
7754 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT);
7755
7394 // copy code 7756 // copy code
7395 memmove(instruction_start(), desc.buffer, desc.instr_size); 7757 memmove(instruction_start(), desc.buffer, desc.instr_size);
7396 7758
7397 // copy reloc info 7759 // copy reloc info
7398 memmove(relocation_start(), 7760 memmove(relocation_start(),
7399 desc.buffer + desc.buffer_size - desc.reloc_size, 7761 desc.buffer + desc.buffer_size - desc.reloc_size,
7400 desc.reloc_size); 7762 desc.reloc_size);
7401 7763
7402 // unbox handles and relocate 7764 // unbox handles and relocate
7403 intptr_t delta = instruction_start() - desc.buffer; 7765 intptr_t delta = instruction_start() - desc.buffer;
7404 int mode_mask = RelocInfo::kCodeTargetMask | 7766 int mode_mask = RelocInfo::kCodeTargetMask |
7405 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 7767 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
7406 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) | 7768 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
7407 RelocInfo::kApplyMask; 7769 RelocInfo::kApplyMask;
7408 Assembler* origin = desc.origin; // Needed to find target_object on X64. 7770 Assembler* origin = desc.origin; // Needed to find target_object on X64.
7409 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { 7771 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
7410 RelocInfo::Mode mode = it.rinfo()->rmode(); 7772 RelocInfo::Mode mode = it.rinfo()->rmode();
7411 if (mode == RelocInfo::EMBEDDED_OBJECT) { 7773 if (mode == RelocInfo::EMBEDDED_OBJECT) {
7412 Handle<Object> p = it.rinfo()->target_object_handle(origin); 7774 Handle<Object> p = it.rinfo()->target_object_handle(origin);
7413 it.rinfo()->set_target_object(*p); 7775 it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER);
7414 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 7776 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
7415 Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle(); 7777 Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle();
7416 it.rinfo()->set_target_cell(*cell); 7778 it.rinfo()->set_target_cell(*cell, SKIP_WRITE_BARRIER);
7417 } else if (RelocInfo::IsCodeTarget(mode)) { 7779 } else if (RelocInfo::IsCodeTarget(mode)) {
7418 // rewrite code handles in inline cache targets to direct 7780 // rewrite code handles in inline cache targets to direct
7419 // pointers to the first instruction in the code object 7781 // pointers to the first instruction in the code object
7420 Handle<Object> p = it.rinfo()->target_object_handle(origin); 7782 Handle<Object> p = it.rinfo()->target_object_handle(origin);
7421 Code* code = Code::cast(*p); 7783 Code* code = Code::cast(*p);
7422 it.rinfo()->set_target_address(code->instruction_start()); 7784 it.rinfo()->set_target_address(code->instruction_start(),
7785 SKIP_WRITE_BARRIER);
7423 } else { 7786 } else {
7424 it.rinfo()->apply(delta); 7787 it.rinfo()->apply(delta);
7425 } 7788 }
7426 } 7789 }
7427 CPU::FlushICache(instruction_start(), instruction_size()); 7790 CPU::FlushICache(instruction_start(), instruction_size());
7428 } 7791 }
7429 7792
7430 7793
7431 // Locate the source position which is closest to the address in the code. This 7794 // Locate the source position which is closest to the address in the code. This
7432 // is using the source position information embedded in the relocation info. 7795 // is using the source position information embedded in the relocation info.
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
7840 (elements()->map()->has_fast_smi_only_elements() || 8203 (elements()->map()->has_fast_smi_only_elements() ||
7841 elements() == heap->empty_fixed_array()); 8204 elements() == heap->empty_fixed_array());
7842 ElementsKind elements_kind = has_fast_smi_only_elements 8205 ElementsKind elements_kind = has_fast_smi_only_elements
7843 ? FAST_SMI_ONLY_ELEMENTS 8206 ? FAST_SMI_ONLY_ELEMENTS
7844 : FAST_ELEMENTS; 8207 : FAST_ELEMENTS;
7845 MaybeObject* maybe = GetElementsTransitionMap(elements_kind); 8208 MaybeObject* maybe = GetElementsTransitionMap(elements_kind);
7846 if (!maybe->ToObject(&object)) return maybe; 8209 if (!maybe->ToObject(&object)) return maybe;
7847 new_map = Map::cast(object); 8210 new_map = Map::cast(object);
7848 } 8211 }
7849 8212
8213 FixedArrayBase* old_elements_raw = elements();
7850 ElementsKind elements_kind = GetElementsKind(); 8214 ElementsKind elements_kind = GetElementsKind();
7851 switch (elements_kind) { 8215 switch (elements_kind) {
7852 case FAST_SMI_ONLY_ELEMENTS: 8216 case FAST_SMI_ONLY_ELEMENTS:
7853 case FAST_ELEMENTS: { 8217 case FAST_ELEMENTS: {
7854 AssertNoAllocation no_gc; 8218 AssertNoAllocation no_gc;
7855 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); 8219 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc));
7856 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 8220 CopyFastElementsToFast(FixedArray::cast(old_elements_raw),
8221 new_elements, mode);
7857 set_map(new_map); 8222 set_map(new_map);
7858 set_elements(new_elements); 8223 set_elements(new_elements);
7859 break; 8224 break;
7860 } 8225 }
7861 case DICTIONARY_ELEMENTS: { 8226 case DICTIONARY_ELEMENTS: {
7862 AssertNoAllocation no_gc; 8227 AssertNoAllocation no_gc;
7863 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 8228 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7864 CopySlowElementsToFast(NumberDictionary::cast(elements()), 8229 CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw),
7865 new_elements, 8230 new_elements,
7866 mode); 8231 mode);
7867 set_map(new_map); 8232 set_map(new_map);
7868 set_elements(new_elements); 8233 set_elements(new_elements);
7869 break; 8234 break;
7870 } 8235 }
7871 case NON_STRICT_ARGUMENTS_ELEMENTS: { 8236 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7872 AssertNoAllocation no_gc; 8237 AssertNoAllocation no_gc;
7873 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 8238 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7874 // The object's map and the parameter map are unchanged, the unaliased 8239 // The object's map and the parameter map are unchanged, the unaliased
7875 // arguments are copied to the new backing store. 8240 // arguments are copied to the new backing store.
7876 FixedArray* parameter_map = FixedArray::cast(elements()); 8241 FixedArray* parameter_map = FixedArray::cast(old_elements_raw);
7877 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 8242 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7878 if (arguments->IsDictionary()) { 8243 if (arguments->IsDictionary()) {
7879 CopySlowElementsToFast(NumberDictionary::cast(arguments), 8244 CopySlowElementsToFast(NumberDictionary::cast(arguments),
7880 new_elements, 8245 new_elements,
7881 mode); 8246 mode);
7882 } else { 8247 } else {
7883 CopyFastElementsToFast(arguments, new_elements, mode); 8248 CopyFastElementsToFast(arguments, new_elements, mode);
7884 } 8249 }
7885 parameter_map->set(1, new_elements); 8250 parameter_map->set(1, new_elements);
7886 break; 8251 break;
7887 } 8252 }
7888 case FAST_DOUBLE_ELEMENTS: { 8253 case FAST_DOUBLE_ELEMENTS: {
7889 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements()); 8254 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw);
7890 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); 8255 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
7891 // Fill out the new array with this content and array holes. 8256 // Fill out the new array with this content and array holes.
7892 for (uint32_t i = 0; i < old_length; i++) { 8257 for (uint32_t i = 0; i < old_length; i++) {
7893 if (!old_elements->is_the_hole(i)) { 8258 if (!old_elements->is_the_hole(i)) {
7894 Object* obj; 8259 Object* obj;
7895 // Objects must be allocated in the old object space, since the 8260 // Objects must be allocated in the old object space, since the
7896 // overall number of HeapNumbers needed for the conversion might 8261 // overall number of HeapNumbers needed for the conversion might
7897 // exceed the capacity of new space, and we would fail repeatedly 8262 // exceed the capacity of new space, and we would fail repeatedly
7898 // trying to convert the FixedDoubleArray. 8263 // trying to convert the FixedDoubleArray.
7899 MaybeObject* maybe_value_object = 8264 MaybeObject* maybe_value_object =
(...skipping 17 matching lines...) Expand all
7917 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8282 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7918 case EXTERNAL_INT_ELEMENTS: 8283 case EXTERNAL_INT_ELEMENTS:
7919 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8284 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7920 case EXTERNAL_FLOAT_ELEMENTS: 8285 case EXTERNAL_FLOAT_ELEMENTS:
7921 case EXTERNAL_DOUBLE_ELEMENTS: 8286 case EXTERNAL_DOUBLE_ELEMENTS:
7922 case EXTERNAL_PIXEL_ELEMENTS: 8287 case EXTERNAL_PIXEL_ELEMENTS:
7923 UNREACHABLE(); 8288 UNREACHABLE();
7924 break; 8289 break;
7925 } 8290 }
7926 8291
8292 if (FLAG_trace_elements_transitions) {
8293 PrintElementsTransition(stdout, elements_kind, old_elements_raw,
8294 FAST_ELEMENTS, new_elements);
8295 }
8296
7927 // Update the length if necessary. 8297 // Update the length if necessary.
7928 if (IsJSArray()) { 8298 if (IsJSArray()) {
7929 JSArray::cast(this)->set_length(Smi::FromInt(length)); 8299 JSArray::cast(this)->set_length(Smi::FromInt(length));
7930 } 8300 }
7931 8301
7932 return new_elements; 8302 return new_elements;
7933 } 8303 }
7934 8304
7935 8305
7936 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 8306 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
7937 int capacity, 8307 int capacity,
7938 int length) { 8308 int length) {
7939 Heap* heap = GetHeap(); 8309 Heap* heap = GetHeap();
7940 // We should never end in here with a pixel or external array. 8310 // We should never end in here with a pixel or external array.
7941 ASSERT(!HasExternalArrayElements()); 8311 ASSERT(!HasExternalArrayElements());
7942 8312
7943 Object* obj; 8313 Object* obj;
7944 { MaybeObject* maybe_obj = 8314 { MaybeObject* maybe_obj =
7945 heap->AllocateUninitializedFixedDoubleArray(capacity); 8315 heap->AllocateUninitializedFixedDoubleArray(capacity);
7946 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8316 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7947 } 8317 }
7948 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); 8318 FixedDoubleArray* elems = FixedDoubleArray::cast(obj);
7949 8319
7950 { MaybeObject* maybe_obj = 8320 { MaybeObject* maybe_obj =
7951 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS); 8321 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS);
7952 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8322 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7953 } 8323 }
7954 Map* new_map = Map::cast(obj); 8324 Map* new_map = Map::cast(obj);
7955 8325
8326 FixedArrayBase* old_elements = elements();
8327 ElementsKind elements_kind(GetElementsKind());
7956 AssertNoAllocation no_gc; 8328 AssertNoAllocation no_gc;
7957 switch (GetElementsKind()) { 8329 switch (elements_kind) {
7958 case FAST_SMI_ONLY_ELEMENTS: 8330 case FAST_SMI_ONLY_ELEMENTS:
7959 case FAST_ELEMENTS: { 8331 case FAST_ELEMENTS: {
7960 elems->Initialize(FixedArray::cast(elements())); 8332 elems->Initialize(FixedArray::cast(old_elements));
7961 break; 8333 break;
7962 } 8334 }
7963 case FAST_DOUBLE_ELEMENTS: { 8335 case FAST_DOUBLE_ELEMENTS: {
7964 elems->Initialize(FixedDoubleArray::cast(elements())); 8336 elems->Initialize(FixedDoubleArray::cast(old_elements));
7965 break; 8337 break;
7966 } 8338 }
7967 case DICTIONARY_ELEMENTS: { 8339 case DICTIONARY_ELEMENTS: {
7968 elems->Initialize(NumberDictionary::cast(elements())); 8340 elems->Initialize(NumberDictionary::cast(old_elements));
7969 break; 8341 break;
7970 } 8342 }
7971 default: 8343 default:
7972 UNREACHABLE(); 8344 UNREACHABLE();
7973 break; 8345 break;
7974 } 8346 }
7975 8347
8348 if (FLAG_trace_elements_transitions) {
8349 PrintElementsTransition(stdout, elements_kind, old_elements,
8350 FAST_DOUBLE_ELEMENTS, elems);
8351 }
8352
7976 ASSERT(new_map->has_fast_double_elements()); 8353 ASSERT(new_map->has_fast_double_elements());
7977 set_map(new_map); 8354 set_map(new_map);
7978 ASSERT(elems->IsFixedDoubleArray()); 8355 ASSERT(elems->IsFixedDoubleArray());
7979 set_elements(elems); 8356 set_elements(elems);
7980 8357
7981 if (IsJSArray()) { 8358 if (IsJSArray()) {
7982 JSArray::cast(this)->set_length(Smi::FromInt(length)); 8359 JSArray::cast(this)->set_length(Smi::FromInt(length));
7983 } 8360 }
7984 8361
7985 return this; 8362 return this;
7986 } 8363 }
7987 8364
7988 8365
7989 MaybeObject* JSObject::SetSlowElements(Object* len) { 8366 MaybeObject* JSObject::SetSlowElements(Object* len) {
7990 // We should never end in here with a pixel or external array. 8367 // We should never end in here with a pixel or external array.
7991 ASSERT(!HasExternalArrayElements()); 8368 ASSERT(!HasExternalArrayElements());
7992 8369
7993 uint32_t new_length = static_cast<uint32_t>(len->Number()); 8370 uint32_t new_length = static_cast<uint32_t>(len->Number());
7994 8371
7995 switch (GetElementsKind()) { 8372 FixedArrayBase* old_elements = elements();
8373 ElementsKind elements_kind = GetElementsKind();
8374 switch (elements_kind) {
7996 case FAST_SMI_ONLY_ELEMENTS: 8375 case FAST_SMI_ONLY_ELEMENTS:
7997 case FAST_ELEMENTS: 8376 case FAST_ELEMENTS:
7998 case FAST_DOUBLE_ELEMENTS: { 8377 case FAST_DOUBLE_ELEMENTS: {
7999 // Make sure we never try to shrink dense arrays into sparse arrays. 8378 // Make sure we never try to shrink dense arrays into sparse arrays.
8000 ASSERT(static_cast<uint32_t>( 8379 ASSERT(static_cast<uint32_t>(old_elements->length()) <= new_length);
8001 FixedArrayBase::cast(elements())->length()) <= new_length);
8002 MaybeObject* result = NormalizeElements(); 8380 MaybeObject* result = NormalizeElements();
8003 if (result->IsFailure()) return result; 8381 if (result->IsFailure()) return result;
8004 8382
8005 // Update length for JSArrays. 8383 // Update length for JSArrays.
8006 if (IsJSArray()) JSArray::cast(this)->set_length(len); 8384 if (IsJSArray()) JSArray::cast(this)->set_length(len);
8007 break; 8385 break;
8008 } 8386 }
8009 case DICTIONARY_ELEMENTS: { 8387 case DICTIONARY_ELEMENTS: {
8010 if (IsJSArray()) { 8388 if (IsJSArray()) {
8011 uint32_t old_length = 8389 uint32_t old_length =
(...skipping 11 matching lines...) Expand all
8023 case EXTERNAL_SHORT_ELEMENTS: 8401 case EXTERNAL_SHORT_ELEMENTS:
8024 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8402 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
8025 case EXTERNAL_INT_ELEMENTS: 8403 case EXTERNAL_INT_ELEMENTS:
8026 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8404 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
8027 case EXTERNAL_FLOAT_ELEMENTS: 8405 case EXTERNAL_FLOAT_ELEMENTS:
8028 case EXTERNAL_DOUBLE_ELEMENTS: 8406 case EXTERNAL_DOUBLE_ELEMENTS:
8029 case EXTERNAL_PIXEL_ELEMENTS: 8407 case EXTERNAL_PIXEL_ELEMENTS:
8030 UNREACHABLE(); 8408 UNREACHABLE();
8031 break; 8409 break;
8032 } 8410 }
8411
8412 if (FLAG_trace_elements_transitions) {
8413 PrintElementsTransition(stdout, elements_kind, old_elements,
8414 DICTIONARY_ELEMENTS, elements());
8415 }
8416
8033 return this; 8417 return this;
8034 } 8418 }
8035 8419
8036 8420
8037 MaybeObject* JSArray::Initialize(int capacity) { 8421 MaybeObject* JSArray::Initialize(int capacity) {
8038 Heap* heap = GetHeap(); 8422 Heap* heap = GetHeap();
8039 ASSERT(capacity >= 0); 8423 ASSERT(capacity >= 0);
8040 set_length(Smi::FromInt(0)); 8424 set_length(Smi::FromInt(0));
8041 FixedArray* new_elements; 8425 FixedArray* new_elements;
8042 if (capacity == 0) { 8426 if (capacity == 0) {
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
8950 if (maybe->IsFailure()) return maybe; 9334 if (maybe->IsFailure()) return maybe;
8951 FixedDoubleArray::cast(elements())->set(index, value->Number()); 9335 FixedDoubleArray::cast(elements())->set(index, value->Number());
8952 return value; 9336 return value;
8953 } 9337 }
8954 // Change elements kind from SMI_ONLY to generic FAST if necessary. 9338 // Change elements kind from SMI_ONLY to generic FAST if necessary.
8955 if (HasFastSmiOnlyElements() && !value->IsSmi()) { 9339 if (HasFastSmiOnlyElements() && !value->IsSmi()) {
8956 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS); 9340 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS);
8957 Map* new_map; 9341 Map* new_map;
8958 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; 9342 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
8959 set_map(new_map); 9343 set_map(new_map);
9344 if (FLAG_trace_elements_transitions) {
9345 PrintElementsTransition(stdout, FAST_SMI_ONLY_ELEMENTS, elements(),
9346 FAST_ELEMENTS, elements());
9347 }
8960 } 9348 }
8961 // Increase backing store capacity if that's been decided previously. 9349 // Increase backing store capacity if that's been decided previously.
8962 if (new_capacity != capacity) { 9350 if (new_capacity != capacity) {
8963 Object* new_elements; 9351 Object* new_elements;
8964 SetFastElementsCapacityMode set_capacity_mode = 9352 SetFastElementsCapacityMode set_capacity_mode =
8965 value->IsSmi() && HasFastSmiOnlyElements() 9353 value->IsSmi() && HasFastSmiOnlyElements()
8966 ? kAllowSmiOnlyElements 9354 ? kAllowSmiOnlyElements
8967 : kDontAllowSmiOnlyElements; 9355 : kDontAllowSmiOnlyElements;
8968 MaybeObject* maybe = 9356 MaybeObject* maybe =
8969 SetFastElementsCapacityAndLength(new_capacity, 9357 SetFastElementsCapacityAndLength(new_capacity,
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
9306 } 9694 }
9307 } 9695 }
9308 } 9696 }
9309 // All possible cases have been handled above. Add a return to avoid the 9697 // All possible cases have been handled above. Add a return to avoid the
9310 // complaints from the compiler. 9698 // complaints from the compiler.
9311 UNREACHABLE(); 9699 UNREACHABLE();
9312 return isolate->heap()->null_value(); 9700 return isolate->heap()->null_value();
9313 } 9701 }
9314 9702
9315 9703
9704 MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind(
9705 ElementsKind to_kind) {
9706 ElementsKind from_kind = map()->elements_kind();
9707 FixedArrayBase* elms = FixedArrayBase::cast(elements());
9708 uint32_t capacity = static_cast<uint32_t>(elms->length());
9709 uint32_t length = capacity;
9710 if (IsJSArray()) {
9711 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
9712 }
9713 if (from_kind == FAST_SMI_ONLY_ELEMENTS) {
9714 if (to_kind == FAST_DOUBLE_ELEMENTS) {
9715 MaybeObject* maybe_result =
9716 SetFastDoubleElementsCapacityAndLength(capacity, length);
9717 if (maybe_result->IsFailure()) return maybe_result;
9718 return this;
9719 } else if (to_kind == FAST_ELEMENTS) {
9720 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS);
9721 Map* new_map;
9722 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
9723 set_map(new_map);
9724 return this;
9725 }
9726 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) {
9727 MaybeObject* maybe_result = SetFastElementsCapacityAndLength(
9728 capacity, length, kDontAllowSmiOnlyElements);
9729 if (maybe_result->IsFailure()) return maybe_result;
9730 return this;
9731 }
9732 // This method should never be called for any other case than the ones
9733 // handled above.
9734 UNREACHABLE();
9735 return GetIsolate()->heap()->null_value();
9736 }
9737
9738
9739 // static
9740 bool Map::IsValidElementsTransition(ElementsKind from_kind,
9741 ElementsKind to_kind) {
9742 return
9743 (from_kind == FAST_SMI_ONLY_ELEMENTS &&
9744 (to_kind == FAST_DOUBLE_ELEMENTS || to_kind == FAST_ELEMENTS)) ||
9745 (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS);
9746 }
9747
9748
9316 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, 9749 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
9317 Object* value) { 9750 Object* value) {
9318 uint32_t old_len = 0; 9751 uint32_t old_len = 0;
9319 CHECK(length()->ToArrayIndex(&old_len)); 9752 CHECK(length()->ToArrayIndex(&old_len));
9320 // Check to see if we need to update the length. For now, we make 9753 // Check to see if we need to update the length. For now, we make
9321 // sure that the length stays within 32-bits (unsigned). 9754 // sure that the length stays within 32-bits (unsigned).
9322 if (index >= old_len && index != 0xffffffff) { 9755 if (index >= old_len && index != 0xffffffff) {
9323 Object* len; 9756 Object* len;
9324 { MaybeObject* maybe_len = 9757 { MaybeObject* maybe_len =
9325 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); 9758 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
9572 constructor->shared()->get_api_func_data()->indexed_property_handler(); 10005 constructor->shared()->get_api_func_data()->indexed_property_handler();
9573 return InterceptorInfo::cast(result); 10006 return InterceptorInfo::cast(result);
9574 } 10007 }
9575 10008
9576 10009
9577 MaybeObject* JSObject::GetPropertyPostInterceptor( 10010 MaybeObject* JSObject::GetPropertyPostInterceptor(
9578 JSReceiver* receiver, 10011 JSReceiver* receiver,
9579 String* name, 10012 String* name,
9580 PropertyAttributes* attributes) { 10013 PropertyAttributes* attributes) {
9581 // Check local property in holder, ignore interceptor. 10014 // Check local property in holder, ignore interceptor.
9582 LookupResult result; 10015 LookupResult result(GetIsolate());
9583 LocalLookupRealNamedProperty(name, &result); 10016 LocalLookupRealNamedProperty(name, &result);
9584 if (result.IsProperty()) { 10017 if (result.IsProperty()) {
9585 return GetProperty(receiver, &result, name, attributes); 10018 return GetProperty(receiver, &result, name, attributes);
9586 } 10019 }
9587 // Continue searching via the prototype chain. 10020 // Continue searching via the prototype chain.
9588 Object* pt = GetPrototype(); 10021 Object* pt = GetPrototype();
9589 *attributes = ABSENT; 10022 *attributes = ABSENT;
9590 if (pt->IsNull()) return GetHeap()->undefined_value(); 10023 if (pt->IsNull()) return GetHeap()->undefined_value();
9591 return pt->GetPropertyWithReceiver(receiver, name, attributes); 10024 return pt->GetPropertyWithReceiver(receiver, name, attributes);
9592 } 10025 }
9593 10026
9594 10027
9595 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( 10028 MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
9596 JSReceiver* receiver, 10029 JSReceiver* receiver,
9597 String* name, 10030 String* name,
9598 PropertyAttributes* attributes) { 10031 PropertyAttributes* attributes) {
9599 // Check local property in holder, ignore interceptor. 10032 // Check local property in holder, ignore interceptor.
9600 LookupResult result; 10033 LookupResult result(GetIsolate());
9601 LocalLookupRealNamedProperty(name, &result); 10034 LocalLookupRealNamedProperty(name, &result);
9602 if (result.IsProperty()) { 10035 if (result.IsProperty()) {
9603 return GetProperty(receiver, &result, name, attributes); 10036 return GetProperty(receiver, &result, name, attributes);
9604 } 10037 }
9605 return GetHeap()->undefined_value(); 10038 return GetHeap()->undefined_value();
9606 } 10039 }
9607 10040
9608 10041
9609 MaybeObject* JSObject::GetPropertyWithInterceptor( 10042 MaybeObject* JSObject::GetPropertyWithInterceptor(
9610 JSReceiver* receiver, 10043 JSReceiver* receiver,
(...skipping 30 matching lines...) Expand all
9641 *receiver_handle, 10074 *receiver_handle,
9642 *name_handle, 10075 *name_handle,
9643 attributes); 10076 attributes);
9644 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 10077 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
9645 return result; 10078 return result;
9646 } 10079 }
9647 10080
9648 10081
9649 bool JSObject::HasRealNamedProperty(String* key) { 10082 bool JSObject::HasRealNamedProperty(String* key) {
9650 // Check access rights if needed. 10083 // Check access rights if needed.
10084 Isolate* isolate = GetIsolate();
9651 if (IsAccessCheckNeeded()) { 10085 if (IsAccessCheckNeeded()) {
9652 Heap* heap = GetHeap(); 10086 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
9653 if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { 10087 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9654 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9655 return false; 10088 return false;
9656 } 10089 }
9657 } 10090 }
9658 10091
9659 LookupResult result; 10092 LookupResult result(isolate);
9660 LocalLookupRealNamedProperty(key, &result); 10093 LocalLookupRealNamedProperty(key, &result);
9661 return result.IsProperty() && (result.type() != INTERCEPTOR); 10094 return result.IsProperty() && (result.type() != INTERCEPTOR);
9662 } 10095 }
9663 10096
9664 10097
9665 bool JSObject::HasRealElementProperty(uint32_t index) { 10098 bool JSObject::HasRealElementProperty(uint32_t index) {
9666 // Check access rights if needed. 10099 // Check access rights if needed.
9667 if (IsAccessCheckNeeded()) { 10100 if (IsAccessCheckNeeded()) {
9668 Heap* heap = GetHeap(); 10101 Heap* heap = GetHeap();
9669 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 10102 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
9718 break; 10151 break;
9719 } 10152 }
9720 // All possibilities have been handled above already. 10153 // All possibilities have been handled above already.
9721 UNREACHABLE(); 10154 UNREACHABLE();
9722 return GetHeap()->null_value(); 10155 return GetHeap()->null_value();
9723 } 10156 }
9724 10157
9725 10158
9726 bool JSObject::HasRealNamedCallbackProperty(String* key) { 10159 bool JSObject::HasRealNamedCallbackProperty(String* key) {
9727 // Check access rights if needed. 10160 // Check access rights if needed.
10161 Isolate* isolate = GetIsolate();
9728 if (IsAccessCheckNeeded()) { 10162 if (IsAccessCheckNeeded()) {
9729 Heap* heap = GetHeap(); 10163 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
9730 if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { 10164 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9731 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9732 return false; 10165 return false;
9733 } 10166 }
9734 } 10167 }
9735 10168
9736 LookupResult result; 10169 LookupResult result(isolate);
9737 LocalLookupRealNamedProperty(key, &result); 10170 LocalLookupRealNamedProperty(key, &result);
9738 return result.IsProperty() && (result.type() == CALLBACKS); 10171 return result.IsProperty() && (result.type() == CALLBACKS);
9739 } 10172 }
9740 10173
9741 10174
9742 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 10175 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
9743 if (HasFastProperties()) { 10176 if (HasFastProperties()) {
9744 DescriptorArray* descs = map()->instance_descriptors(); 10177 DescriptorArray* descs = map()->instance_descriptors();
9745 int result = 0; 10178 int result = 0;
9746 for (int i = 0; i < descs->number_of_descriptors(); i++) { 10179 for (int i = 0; i < descs->number_of_descriptors(); i++) {
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
10591 11024
10592 // Force instantiation of template instances class. 11025 // Force instantiation of template instances class.
10593 // Please note this list is compiler dependent. 11026 // Please note this list is compiler dependent.
10594 11027
10595 template class HashTable<SymbolTableShape, HashTableKey*>; 11028 template class HashTable<SymbolTableShape, HashTableKey*>;
10596 11029
10597 template class HashTable<CompilationCacheShape, HashTableKey*>; 11030 template class HashTable<CompilationCacheShape, HashTableKey*>;
10598 11031
10599 template class HashTable<MapCacheShape, HashTableKey*>; 11032 template class HashTable<MapCacheShape, HashTableKey*>;
10600 11033
10601 template class HashTable<ObjectHashTableShape, JSReceiver*>; 11034 template class HashTable<ObjectHashTableShape<1>, Object*>;
11035
11036 template class HashTable<ObjectHashTableShape<2>, Object*>;
10602 11037
10603 template class Dictionary<StringDictionaryShape, String*>; 11038 template class Dictionary<StringDictionaryShape, String*>;
10604 11039
10605 template class Dictionary<NumberDictionaryShape, uint32_t>; 11040 template class Dictionary<NumberDictionaryShape, uint32_t>;
10606 11041
10607 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( 11042 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
10608 int); 11043 int);
10609 11044
10610 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( 11045 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
10611 int); 11046 int);
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
11082 } 11517 }
11083 11518
11084 11519
11085 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { 11520 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
11086 ASSERT(!HasFastProperties()); 11521 ASSERT(!HasFastProperties());
11087 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 11522 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
11088 return JSGlobalPropertyCell::cast(value); 11523 return JSGlobalPropertyCell::cast(value);
11089 } 11524 }
11090 11525
11091 11526
11527 Handle<JSGlobalPropertyCell> GlobalObject::EnsurePropertyCell(
11528 Handle<GlobalObject> global,
11529 Handle<String> name) {
11530 Isolate* isolate = global->GetIsolate();
11531 CALL_HEAP_FUNCTION(isolate,
11532 global->EnsurePropertyCell(*name),
11533 JSGlobalPropertyCell);
11534 }
11535
11536
11092 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { 11537 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) {
11093 ASSERT(!HasFastProperties()); 11538 ASSERT(!HasFastProperties());
11094 int entry = property_dictionary()->FindEntry(name); 11539 int entry = property_dictionary()->FindEntry(name);
11095 if (entry == StringDictionary::kNotFound) { 11540 if (entry == StringDictionary::kNotFound) {
11096 Heap* heap = GetHeap(); 11541 Heap* heap = GetHeap();
11097 Object* cell; 11542 Object* cell;
11098 { MaybeObject* maybe_cell = 11543 { MaybeObject* maybe_cell =
11099 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); 11544 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value());
11100 if (!maybe_cell->ToObject(&cell)) return maybe_cell; 11545 if (!maybe_cell->ToObject(&cell)) return maybe_cell;
11101 } 11546 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
11319 cache->ElementAdded(); 11764 cache->ElementAdded();
11320 return cache; 11765 return cache;
11321 } 11766 }
11322 11767
11323 11768
11324 MaybeObject* CompilationCacheTable::PutEval(String* src, 11769 MaybeObject* CompilationCacheTable::PutEval(String* src,
11325 Context* context, 11770 Context* context,
11326 SharedFunctionInfo* value) { 11771 SharedFunctionInfo* value) {
11327 StringSharedKey key(src, 11772 StringSharedKey key(src,
11328 context->closure()->shared(), 11773 context->closure()->shared(),
11329 value->strict_mode() ? kStrictMode : kNonStrictMode); 11774 value->strict_mode_flag());
11330 Object* obj; 11775 Object* obj;
11331 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 11776 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
11332 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11777 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11333 } 11778 }
11334 11779
11335 CompilationCacheTable* cache = 11780 CompilationCacheTable* cache =
11336 reinterpret_cast<CompilationCacheTable*>(obj); 11781 reinterpret_cast<CompilationCacheTable*>(obj);
11337 int entry = cache->FindInsertionEntry(key.Hash()); 11782 int entry = cache->FindInsertionEntry(key.Hash());
11338 11783
11339 Object* k; 11784 Object* k;
(...skipping 28 matching lines...) Expand all
11368 return cache; 11813 return cache;
11369 } 11814 }
11370 11815
11371 11816
11372 void CompilationCacheTable::Remove(Object* value) { 11817 void CompilationCacheTable::Remove(Object* value) {
11373 Object* null_value = GetHeap()->null_value(); 11818 Object* null_value = GetHeap()->null_value();
11374 for (int entry = 0, size = Capacity(); entry < size; entry++) { 11819 for (int entry = 0, size = Capacity(); entry < size; entry++) {
11375 int entry_index = EntryToIndex(entry); 11820 int entry_index = EntryToIndex(entry);
11376 int value_index = entry_index + 1; 11821 int value_index = entry_index + 1;
11377 if (get(value_index) == value) { 11822 if (get(value_index) == value) {
11378 fast_set(this, entry_index, null_value); 11823 NoWriteBarrierSet(this, entry_index, null_value);
11379 fast_set(this, value_index, null_value); 11824 NoWriteBarrierSet(this, value_index, null_value);
11380 ElementRemoved(); 11825 ElementRemoved();
11381 } 11826 }
11382 } 11827 }
11383 return; 11828 return;
11384 } 11829 }
11385 11830
11386 11831
11387 // SymbolsKey used for HashTable where key is array of symbols. 11832 // SymbolsKey used for HashTable where key is array of symbols.
11388 class SymbolsKey : public HashTableKey { 11833 class SymbolsKey : public HashTableKey {
11389 public: 11834 public:
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
11841 ASSERT(type != FIELD); 12286 ASSERT(type != FIELD);
11842 instance_descriptor_length++; 12287 instance_descriptor_length++;
11843 if (type == NORMAL && 12288 if (type == NORMAL &&
11844 (!value->IsJSFunction() || heap->InNewSpace(value))) { 12289 (!value->IsJSFunction() || heap->InNewSpace(value))) {
11845 number_of_fields += 1; 12290 number_of_fields += 1;
11846 } 12291 }
11847 } 12292 }
11848 } 12293 }
11849 12294
11850 // Allocate the instance descriptor. 12295 // Allocate the instance descriptor.
11851 Object* descriptors_unchecked; 12296 DescriptorArray* descriptors;
11852 { MaybeObject* maybe_descriptors_unchecked = 12297 { MaybeObject* maybe_descriptors =
11853 DescriptorArray::Allocate(instance_descriptor_length); 12298 DescriptorArray::Allocate(instance_descriptor_length);
11854 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { 12299 if (!maybe_descriptors->To<DescriptorArray>(&descriptors)) {
11855 return maybe_descriptors_unchecked; 12300 return maybe_descriptors;
11856 } 12301 }
11857 } 12302 }
11858 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); 12303
12304 DescriptorArray::WhitenessWitness witness(descriptors);
11859 12305
11860 int inobject_props = obj->map()->inobject_properties(); 12306 int inobject_props = obj->map()->inobject_properties();
11861 int number_of_allocated_fields = 12307 int number_of_allocated_fields =
11862 number_of_fields + unused_property_fields - inobject_props; 12308 number_of_fields + unused_property_fields - inobject_props;
11863 if (number_of_allocated_fields < 0) { 12309 if (number_of_allocated_fields < 0) {
11864 // There is enough inobject space for all fields (including unused). 12310 // There is enough inobject space for all fields (including unused).
11865 number_of_allocated_fields = 0; 12311 number_of_allocated_fields = 0;
11866 unused_property_fields = inobject_props - number_of_fields; 12312 unused_property_fields = inobject_props - number_of_fields;
11867 } 12313 }
11868 12314
(...skipping 17 matching lines...) Expand all
11886 if (!maybe_key->ToObject(&key)) return maybe_key; 12332 if (!maybe_key->ToObject(&key)) return maybe_key;
11887 } 12333 }
11888 PropertyDetails details = DetailsAt(i); 12334 PropertyDetails details = DetailsAt(i);
11889 PropertyType type = details.type(); 12335 PropertyType type = details.type();
11890 12336
11891 if (value->IsJSFunction() && !heap->InNewSpace(value)) { 12337 if (value->IsJSFunction() && !heap->InNewSpace(value)) {
11892 ConstantFunctionDescriptor d(String::cast(key), 12338 ConstantFunctionDescriptor d(String::cast(key),
11893 JSFunction::cast(value), 12339 JSFunction::cast(value),
11894 details.attributes(), 12340 details.attributes(),
11895 details.index()); 12341 details.index());
11896 descriptors->Set(next_descriptor++, &d); 12342 descriptors->Set(next_descriptor++, &d, witness);
11897 } else if (type == NORMAL) { 12343 } else if (type == NORMAL) {
11898 if (current_offset < inobject_props) { 12344 if (current_offset < inobject_props) {
11899 obj->InObjectPropertyAtPut(current_offset, 12345 obj->InObjectPropertyAtPut(current_offset,
11900 value, 12346 value,
11901 UPDATE_WRITE_BARRIER); 12347 UPDATE_WRITE_BARRIER);
11902 } else { 12348 } else {
11903 int offset = current_offset - inobject_props; 12349 int offset = current_offset - inobject_props;
11904 FixedArray::cast(fields)->set(offset, value); 12350 FixedArray::cast(fields)->set(offset, value);
11905 } 12351 }
11906 FieldDescriptor d(String::cast(key), 12352 FieldDescriptor d(String::cast(key),
11907 current_offset++, 12353 current_offset++,
11908 details.attributes(), 12354 details.attributes(),
11909 details.index()); 12355 details.index());
11910 descriptors->Set(next_descriptor++, &d); 12356 descriptors->Set(next_descriptor++, &d, witness);
11911 } else if (type == CALLBACKS) { 12357 } else if (type == CALLBACKS) {
11912 CallbacksDescriptor d(String::cast(key), 12358 CallbacksDescriptor d(String::cast(key),
11913 value, 12359 value,
11914 details.attributes(), 12360 details.attributes(),
11915 details.index()); 12361 details.index());
11916 descriptors->Set(next_descriptor++, &d); 12362 descriptors->Set(next_descriptor++, &d, witness);
11917 } else { 12363 } else {
11918 UNREACHABLE(); 12364 UNREACHABLE();
11919 } 12365 }
11920 } 12366 }
11921 } 12367 }
11922 ASSERT(current_offset == number_of_fields); 12368 ASSERT(current_offset == number_of_fields);
11923 12369
11924 descriptors->Sort(); 12370 descriptors->Sort(witness);
11925 // Allocate new map. 12371 // Allocate new map.
11926 Object* new_map; 12372 Object* new_map;
11927 { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); 12373 { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
11928 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 12374 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
11929 } 12375 }
11930 12376
11931 // Transform the object. 12377 // Transform the object.
11932 obj->set_map(Map::cast(new_map)); 12378 obj->set_map(Map::cast(new_map));
11933 obj->map()->set_instance_descriptors(descriptors); 12379 obj->map()->set_instance_descriptors(descriptors);
11934 obj->map()->set_unused_property_fields(unused_property_fields); 12380 obj->map()->set_unused_property_fields(unused_property_fields);
11935 12381
11936 obj->set_properties(FixedArray::cast(fields)); 12382 obj->set_properties(FixedArray::cast(fields));
11937 ASSERT(obj->IsJSObject()); 12383 ASSERT(obj->IsJSObject());
11938 12384
11939 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 12385 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
11940 // Check that it really works. 12386 // Check that it really works.
11941 ASSERT(obj->HasFastProperties()); 12387 ASSERT(obj->HasFastProperties());
11942 12388
11943 return obj; 12389 return obj;
11944 } 12390 }
11945 12391
11946 12392
11947 Object* ObjectHashTable::Lookup(JSReceiver* key) { 12393 bool ObjectHashSet::Contains(Object* key) {
11948 // If the object does not have an identity hash, it was never used as a key. 12394 // If the object does not have an identity hash, it was never used as a key.
11949 MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION); 12395 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
11950 if (maybe_hash->IsFailure()) return GetHeap()->undefined_value(); 12396 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false;
12397 }
12398 return (FindEntry(key) != kNotFound);
12399 }
12400
12401
12402 MaybeObject* ObjectHashSet::Add(Object* key) {
12403 // Make sure the key object has an identity hash code.
12404 int hash;
12405 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
12406 if (maybe_hash->IsFailure()) return maybe_hash;
12407 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
12408 }
12409 int entry = FindEntry(key);
12410
12411 // Check whether key is already present.
12412 if (entry != kNotFound) return this;
12413
12414 // Check whether the hash set should be extended and add entry.
12415 Object* obj;
12416 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
12417 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
12418 }
12419 ObjectHashSet* table = ObjectHashSet::cast(obj);
12420 entry = table->FindInsertionEntry(hash);
12421 table->set(EntryToIndex(entry), key);
12422 table->ElementAdded();
12423 return table;
12424 }
12425
12426
12427 MaybeObject* ObjectHashSet::Remove(Object* key) {
12428 // If the object does not have an identity hash, it was never used as a key.
12429 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12430 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this;
12431 }
12432 int entry = FindEntry(key);
12433
12434 // Check whether key is actually present.
12435 if (entry == kNotFound) return this;
12436
12437 // Remove entry and try to shrink this hash set.
12438 set_null(EntryToIndex(entry));
12439 ElementRemoved();
12440 return Shrink(key);
12441 }
12442
12443
12444 Object* ObjectHashTable::Lookup(Object* key) {
12445 // If the object does not have an identity hash, it was never used as a key.
12446 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12447 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) {
12448 return GetHeap()->undefined_value();
12449 }
12450 }
11951 int entry = FindEntry(key); 12451 int entry = FindEntry(key);
11952 if (entry == kNotFound) return GetHeap()->undefined_value(); 12452 if (entry == kNotFound) return GetHeap()->undefined_value();
11953 return get(EntryToIndex(entry) + 1); 12453 return get(EntryToIndex(entry) + 1);
11954 } 12454 }
11955 12455
11956 12456
11957 MaybeObject* ObjectHashTable::Put(JSReceiver* key, Object* value) { 12457 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
11958 // Make sure the key object has an identity hash code. 12458 // Make sure the key object has an identity hash code.
11959 int hash; 12459 int hash;
11960 { MaybeObject* maybe_hash = key->GetIdentityHash(ALLOW_CREATION); 12460 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
11961 if (maybe_hash->IsFailure()) return maybe_hash; 12461 if (maybe_hash->IsFailure()) return maybe_hash;
11962 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); 12462 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
11963 } 12463 }
11964 int entry = FindEntry(key); 12464 int entry = FindEntry(key);
11965 12465
11966 // Check whether to perform removal operation. 12466 // Check whether to perform removal operation.
11967 if (value->IsUndefined()) { 12467 if (value->IsUndefined()) {
11968 if (entry == kNotFound) return this; 12468 if (entry == kNotFound) return this;
11969 RemoveEntry(entry); 12469 RemoveEntry(entry);
11970 return Shrink(key); 12470 return Shrink(key);
11971 } 12471 }
11972 12472
11973 // Key is already in table, just overwrite value. 12473 // Key is already in table, just overwrite value.
11974 if (entry != kNotFound) { 12474 if (entry != kNotFound) {
11975 set(EntryToIndex(entry) + 1, value); 12475 set(EntryToIndex(entry) + 1, value);
11976 return this; 12476 return this;
11977 } 12477 }
11978 12478
11979 // Check whether the hash table should be extended. 12479 // Check whether the hash table should be extended.
11980 Object* obj; 12480 Object* obj;
11981 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 12481 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
11982 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 12482 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11983 } 12483 }
11984 ObjectHashTable* table = ObjectHashTable::cast(obj); 12484 ObjectHashTable* table = ObjectHashTable::cast(obj);
11985 table->AddEntry(table->FindInsertionEntry(hash), key, value); 12485 table->AddEntry(table->FindInsertionEntry(hash), key, value);
11986 return table; 12486 return table;
11987 } 12487 }
11988 12488
11989 12489
11990 void ObjectHashTable::AddEntry(int entry, JSReceiver* key, Object* value) { 12490 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
11991 set(EntryToIndex(entry), key); 12491 set(EntryToIndex(entry), key);
11992 set(EntryToIndex(entry) + 1, value); 12492 set(EntryToIndex(entry) + 1, value);
11993 ElementAdded(); 12493 ElementAdded();
11994 } 12494 }
11995 12495
11996 12496
11997 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) { 12497 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) {
11998 set_null(heap, EntryToIndex(entry)); 12498 set_null(heap, EntryToIndex(entry));
11999 set_null(heap, EntryToIndex(entry) + 1); 12499 set_null(heap, EntryToIndex(entry) + 1);
12000 ElementRemoved(); 12500 ElementRemoved();
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
12248 if (break_point_objects()->IsUndefined()) return 0; 12748 if (break_point_objects()->IsUndefined()) return 0;
12249 // Single break point. 12749 // Single break point.
12250 if (!break_point_objects()->IsFixedArray()) return 1; 12750 if (!break_point_objects()->IsFixedArray()) return 1;
12251 // Multiple break points. 12751 // Multiple break points.
12252 return FixedArray::cast(break_point_objects())->length(); 12752 return FixedArray::cast(break_point_objects())->length();
12253 } 12753 }
12254 #endif // ENABLE_DEBUGGER_SUPPORT 12754 #endif // ENABLE_DEBUGGER_SUPPORT
12255 12755
12256 12756
12257 } } // namespace v8::internal 12757 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698