| OLD | NEW |
| 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 25 matching lines...) Expand all Loading... |
| 36 #define V8_OBJECTS_INL_H_ | 36 #define V8_OBJECTS_INL_H_ |
| 37 | 37 |
| 38 #include "elements.h" | 38 #include "elements.h" |
| 39 #include "objects.h" | 39 #include "objects.h" |
| 40 #include "contexts.h" | 40 #include "contexts.h" |
| 41 #include "conversions-inl.h" | 41 #include "conversions-inl.h" |
| 42 #include "heap.h" | 42 #include "heap.h" |
| 43 #include "isolate.h" | 43 #include "isolate.h" |
| 44 #include "property.h" | 44 #include "property.h" |
| 45 #include "spaces.h" | 45 #include "spaces.h" |
| 46 #include "store-buffer.h" |
| 46 #include "v8memory.h" | 47 #include "v8memory.h" |
| 47 | 48 |
| 49 #include "incremental-marking.h" |
| 50 |
| 48 namespace v8 { | 51 namespace v8 { |
| 49 namespace internal { | 52 namespace internal { |
| 50 | 53 |
| 51 PropertyDetails::PropertyDetails(Smi* smi) { | 54 PropertyDetails::PropertyDetails(Smi* smi) { |
| 52 value_ = smi->value(); | 55 value_ = smi->value(); |
| 53 } | 56 } |
| 54 | 57 |
| 55 | 58 |
| 56 Smi* PropertyDetails::AsSmi() { | 59 Smi* PropertyDetails::AsSmi() { |
| 57 return Smi::FromInt(value_); | 60 return Smi::FromInt(value_); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 73 | 76 |
| 74 #define INT_ACCESSORS(holder, name, offset) \ | 77 #define INT_ACCESSORS(holder, name, offset) \ |
| 75 int holder::name() { return READ_INT_FIELD(this, offset); } \ | 78 int holder::name() { return READ_INT_FIELD(this, offset); } \ |
| 76 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } | 79 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } |
| 77 | 80 |
| 78 | 81 |
| 79 #define ACCESSORS(holder, name, type, offset) \ | 82 #define ACCESSORS(holder, name, type, offset) \ |
| 80 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ | 83 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ |
| 81 void holder::set_##name(type* value, WriteBarrierMode mode) { \ | 84 void holder::set_##name(type* value, WriteBarrierMode mode) { \ |
| 82 WRITE_FIELD(this, offset, value); \ | 85 WRITE_FIELD(this, offset, value); \ |
| 83 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \ | 86 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \ |
| 84 } | |
| 85 | |
| 86 | |
| 87 // GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead. | |
| 88 #define ACCESSORS_GCSAFE(holder, name, type, offset) \ | |
| 89 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ | |
| 90 void holder::set_##name(type* value, WriteBarrierMode mode) { \ | |
| 91 WRITE_FIELD(this, offset, value); \ | |
| 92 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \ | |
| 93 } | 87 } |
| 94 | 88 |
| 95 | 89 |
| 96 #define SMI_ACCESSORS(holder, name, offset) \ | 90 #define SMI_ACCESSORS(holder, name, offset) \ |
| 97 int holder::name() { \ | 91 int holder::name() { \ |
| 98 Object* value = READ_FIELD(this, offset); \ | 92 Object* value = READ_FIELD(this, offset); \ |
| 99 return Smi::cast(value)->value(); \ | 93 return Smi::cast(value)->value(); \ |
| 100 } \ | 94 } \ |
| 101 void holder::set_##name(int value) { \ | 95 void holder::set_##name(int value) { \ |
| 102 WRITE_FIELD(this, offset, Smi::FromInt(value)); \ | 96 WRITE_FIELD(this, offset, Smi::FromInt(value)); \ |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 bool Object::IsSmi() { | 134 bool Object::IsSmi() { |
| 141 return HAS_SMI_TAG(this); | 135 return HAS_SMI_TAG(this); |
| 142 } | 136 } |
| 143 | 137 |
| 144 | 138 |
| 145 bool Object::IsHeapObject() { | 139 bool Object::IsHeapObject() { |
| 146 return Internals::HasHeapObjectTag(this); | 140 return Internals::HasHeapObjectTag(this); |
| 147 } | 141 } |
| 148 | 142 |
| 149 | 143 |
| 144 bool Object::NonFailureIsHeapObject() { |
| 145 ASSERT(!this->IsFailure()); |
| 146 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0; |
| 147 } |
| 148 |
| 149 |
| 150 bool Object::IsHeapNumber() { | 150 bool Object::IsHeapNumber() { |
| 151 return Object::IsHeapObject() | 151 return Object::IsHeapObject() |
| 152 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE; | 152 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE; |
| 153 } | 153 } |
| 154 | 154 |
| 155 | 155 |
| 156 bool Object::IsString() { | 156 bool Object::IsString() { |
| 157 return Object::IsHeapObject() | 157 return Object::IsHeapObject() |
| 158 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE; | 158 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE; |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 bool Object::IsSpecObject() { | 162 bool Object::IsSpecObject() { |
| 163 return Object::IsHeapObject() | 163 return Object::IsHeapObject() |
| 164 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE; | 164 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE; |
| 165 } | 165 } |
| 166 | 166 |
| 167 | 167 |
| 168 bool Object::IsSpecFunction() { |
| 169 if (!Object::IsHeapObject()) return false; |
| 170 InstanceType type = HeapObject::cast(this)->map()->instance_type(); |
| 171 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE; |
| 172 } |
| 173 |
| 174 |
| 168 bool Object::IsSymbol() { | 175 bool Object::IsSymbol() { |
| 169 if (!this->IsHeapObject()) return false; | 176 if (!this->IsHeapObject()) return false; |
| 170 uint32_t type = HeapObject::cast(this)->map()->instance_type(); | 177 uint32_t type = HeapObject::cast(this)->map()->instance_type(); |
| 171 // Because the symbol tag is non-zero and no non-string types have the | 178 // Because the symbol tag is non-zero and no non-string types have the |
| 172 // symbol bit set we can test for symbols with a very simple test | 179 // symbol bit set we can test for symbols with a very simple test |
| 173 // operation. | 180 // operation. |
| 174 STATIC_ASSERT(kSymbolTag != 0); | 181 STATIC_ASSERT(kSymbolTag != 0); |
| 175 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE); | 182 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE); |
| 176 return (type & kIsSymbolMask) != 0; | 183 return (type & kIsSymbolMask) != 0; |
| 177 } | 184 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 return IsSmi() || IsHeapNumber(); | 402 return IsSmi() || IsHeapNumber(); |
| 396 } | 403 } |
| 397 | 404 |
| 398 | 405 |
| 399 bool Object::IsByteArray() { | 406 bool Object::IsByteArray() { |
| 400 return Object::IsHeapObject() | 407 return Object::IsHeapObject() |
| 401 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE; | 408 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE; |
| 402 } | 409 } |
| 403 | 410 |
| 404 | 411 |
| 412 bool Object::IsFreeSpace() { |
| 413 return Object::IsHeapObject() |
| 414 && HeapObject::cast(this)->map()->instance_type() == FREE_SPACE_TYPE; |
| 415 } |
| 416 |
| 417 |
| 418 bool Object::IsFiller() { |
| 419 if (!Object::IsHeapObject()) return false; |
| 420 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type(); |
| 421 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE; |
| 422 } |
| 423 |
| 424 |
| 405 bool Object::IsExternalPixelArray() { | 425 bool Object::IsExternalPixelArray() { |
| 406 return Object::IsHeapObject() && | 426 return Object::IsHeapObject() && |
| 407 HeapObject::cast(this)->map()->instance_type() == | 427 HeapObject::cast(this)->map()->instance_type() == |
| 408 EXTERNAL_PIXEL_ARRAY_TYPE; | 428 EXTERNAL_PIXEL_ARRAY_TYPE; |
| 409 } | 429 } |
| 410 | 430 |
| 411 | 431 |
| 412 bool Object::IsExternalArray() { | 432 bool Object::IsExternalArray() { |
| 413 if (!Object::IsHeapObject()) | 433 if (!Object::IsHeapObject()) |
| 414 return false; | 434 return false; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 } | 522 } |
| 503 | 523 |
| 504 | 524 |
| 505 Failure* Failure::cast(MaybeObject* obj) { | 525 Failure* Failure::cast(MaybeObject* obj) { |
| 506 ASSERT(HAS_FAILURE_TAG(obj)); | 526 ASSERT(HAS_FAILURE_TAG(obj)); |
| 507 return reinterpret_cast<Failure*>(obj); | 527 return reinterpret_cast<Failure*>(obj); |
| 508 } | 528 } |
| 509 | 529 |
| 510 | 530 |
| 511 bool Object::IsJSReceiver() { | 531 bool Object::IsJSReceiver() { |
| 532 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 512 return IsHeapObject() && | 533 return IsHeapObject() && |
| 513 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE; | 534 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE; |
| 514 } | 535 } |
| 515 | 536 |
| 516 | 537 |
| 517 bool Object::IsJSObject() { | 538 bool Object::IsJSObject() { |
| 518 return IsJSReceiver() && !IsJSProxy(); | 539 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
| 540 return IsHeapObject() && |
| 541 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE; |
| 519 } | 542 } |
| 520 | 543 |
| 521 | 544 |
| 522 bool Object::IsJSProxy() { | 545 bool Object::IsJSProxy() { |
| 523 return Object::IsHeapObject() && | 546 if (!Object::IsHeapObject()) return false; |
| 524 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE || | 547 InstanceType type = HeapObject::cast(this)->map()->instance_type(); |
| 525 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE); | 548 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE; |
| 526 } | 549 } |
| 527 | 550 |
| 528 | 551 |
| 529 bool Object::IsJSFunctionProxy() { | 552 bool Object::IsJSFunctionProxy() { |
| 530 return Object::IsHeapObject() && | 553 return Object::IsHeapObject() && |
| 531 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE; | 554 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE; |
| 532 } | 555 } |
| 533 | 556 |
| 534 | 557 |
| 535 bool Object::IsJSWeakMap() { | 558 bool Object::IsJSWeakMap() { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 } | 658 } |
| 636 | 659 |
| 637 | 660 |
| 638 bool Object::IsCode() { | 661 bool Object::IsCode() { |
| 639 return Object::IsHeapObject() | 662 return Object::IsHeapObject() |
| 640 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE; | 663 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE; |
| 641 } | 664 } |
| 642 | 665 |
| 643 | 666 |
| 644 bool Object::IsOddball() { | 667 bool Object::IsOddball() { |
| 645 ASSERT(HEAP->is_safe_to_read_maps()); | |
| 646 return Object::IsHeapObject() | 668 return Object::IsHeapObject() |
| 647 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE; | 669 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE; |
| 648 } | 670 } |
| 649 | 671 |
| 650 | 672 |
| 651 bool Object::IsJSGlobalPropertyCell() { | 673 bool Object::IsJSGlobalPropertyCell() { |
| 652 return Object::IsHeapObject() | 674 return Object::IsHeapObject() |
| 653 && HeapObject::cast(this)->map()->instance_type() | 675 && HeapObject::cast(this)->map()->instance_type() |
| 654 == JS_GLOBAL_PROPERTY_CELL_TYPE; | 676 == JS_GLOBAL_PROPERTY_CELL_TYPE; |
| 655 } | 677 } |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 | 954 |
| 933 #define FIELD_ADDR(p, offset) \ | 955 #define FIELD_ADDR(p, offset) \ |
| 934 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) | 956 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) |
| 935 | 957 |
| 936 #define READ_FIELD(p, offset) \ | 958 #define READ_FIELD(p, offset) \ |
| 937 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) | 959 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) |
| 938 | 960 |
| 939 #define WRITE_FIELD(p, offset, value) \ | 961 #define WRITE_FIELD(p, offset, value) \ |
| 940 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) | 962 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) |
| 941 | 963 |
| 942 // TODO(isolates): Pass heap in to these macros. | 964 #define WRITE_BARRIER(heap, object, offset, value) \ |
| 943 #define WRITE_BARRIER(object, offset) \ | 965 heap->incremental_marking()->RecordWrite( \ |
| 944 object->GetHeap()->RecordWrite(object->address(), offset); | 966 object, HeapObject::RawField(object, offset), value); \ |
| 967 if (heap->InNewSpace(value)) { \ |
| 968 heap->RecordWrite(object->address(), offset); \ |
| 969 } |
| 945 | 970 |
| 946 // CONDITIONAL_WRITE_BARRIER must be issued after the actual | 971 #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \ |
| 947 // write due to the assert validating the written value. | 972 if (mode == UPDATE_WRITE_BARRIER) { \ |
| 948 #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \ | 973 heap->incremental_marking()->RecordWrite( \ |
| 949 if (mode == UPDATE_WRITE_BARRIER) { \ | 974 object, HeapObject::RawField(object, offset), value); \ |
| 950 heap->RecordWrite(object->address(), offset); \ | 975 if (heap->InNewSpace(value)) { \ |
| 951 } else { \ | 976 heap->RecordWrite(object->address(), offset); \ |
| 952 ASSERT(mode == SKIP_WRITE_BARRIER); \ | 977 } \ |
| 953 ASSERT(heap->InNewSpace(object) || \ | |
| 954 !heap->InNewSpace(READ_FIELD(object, offset)) || \ | |
| 955 Page::FromAddress(object->address())-> \ | |
| 956 IsRegionDirty(object->address() + offset)); \ | |
| 957 } | 978 } |
| 958 | 979 |
| 959 #ifndef V8_TARGET_ARCH_MIPS | 980 #ifndef V8_TARGET_ARCH_MIPS |
| 960 #define READ_DOUBLE_FIELD(p, offset) \ | 981 #define READ_DOUBLE_FIELD(p, offset) \ |
| 961 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) | 982 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) |
| 962 #else // V8_TARGET_ARCH_MIPS | 983 #else // V8_TARGET_ARCH_MIPS |
| 963 // Prevent gcc from using load-double (mips ldc1) on (possibly) | 984 // Prevent gcc from using load-double (mips ldc1) on (possibly) |
| 964 // non-64-bit aligned HeapNumber::value. | 985 // non-64-bit aligned HeapNumber::value. |
| 965 static inline double read_double_field(void* p, int offset) { | 986 static inline double read_double_field(void* p, int offset) { |
| 966 union conversion { | 987 union conversion { |
| 967 double d; | 988 double d; |
| 968 uint32_t u[2]; | 989 uint32_t u[2]; |
| 969 } c; | 990 } c; |
| 970 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))); | 991 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))); |
| 971 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))); | 992 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))); |
| 972 return c.d; | 993 return c.d; |
| 973 } | 994 } |
| 974 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset) | 995 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset) |
| 975 #endif // V8_TARGET_ARCH_MIPS | 996 #endif // V8_TARGET_ARCH_MIPS |
| 976 | 997 |
| 977 | |
| 978 #ifndef V8_TARGET_ARCH_MIPS | 998 #ifndef V8_TARGET_ARCH_MIPS |
| 979 #define WRITE_DOUBLE_FIELD(p, offset, value) \ | 999 #define WRITE_DOUBLE_FIELD(p, offset, value) \ |
| 980 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) | 1000 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) |
| 981 #else // V8_TARGET_ARCH_MIPS | 1001 #else // V8_TARGET_ARCH_MIPS |
| 982 // Prevent gcc from using store-double (mips sdc1) on (possibly) | 1002 // Prevent gcc from using store-double (mips sdc1) on (possibly) |
| 983 // non-64-bit aligned HeapNumber::value. | 1003 // non-64-bit aligned HeapNumber::value. |
| 984 static inline void write_double_field(void* p, int offset, | 1004 static inline void write_double_field(void* p, int offset, |
| 985 double value) { | 1005 double value) { |
| 986 union conversion { | 1006 union conversion { |
| 987 double d; | 1007 double d; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 return MapWord(reinterpret_cast<uintptr_t>(raw)); | 1182 return MapWord(reinterpret_cast<uintptr_t>(raw)); |
| 1163 } | 1183 } |
| 1164 | 1184 |
| 1165 | 1185 |
| 1166 HeapObject* MapWord::ToForwardingAddress() { | 1186 HeapObject* MapWord::ToForwardingAddress() { |
| 1167 ASSERT(IsForwardingAddress()); | 1187 ASSERT(IsForwardingAddress()); |
| 1168 return HeapObject::FromAddress(reinterpret_cast<Address>(value_)); | 1188 return HeapObject::FromAddress(reinterpret_cast<Address>(value_)); |
| 1169 } | 1189 } |
| 1170 | 1190 |
| 1171 | 1191 |
| 1172 bool MapWord::IsMarked() { | |
| 1173 return (value_ & kMarkingMask) == 0; | |
| 1174 } | |
| 1175 | |
| 1176 | |
| 1177 void MapWord::SetMark() { | |
| 1178 value_ &= ~kMarkingMask; | |
| 1179 } | |
| 1180 | |
| 1181 | |
| 1182 void MapWord::ClearMark() { | |
| 1183 value_ |= kMarkingMask; | |
| 1184 } | |
| 1185 | |
| 1186 | |
| 1187 bool MapWord::IsOverflowed() { | |
| 1188 return (value_ & kOverflowMask) != 0; | |
| 1189 } | |
| 1190 | |
| 1191 | |
| 1192 void MapWord::SetOverflow() { | |
| 1193 value_ |= kOverflowMask; | |
| 1194 } | |
| 1195 | |
| 1196 | |
| 1197 void MapWord::ClearOverflow() { | |
| 1198 value_ &= ~kOverflowMask; | |
| 1199 } | |
| 1200 | |
| 1201 | |
| 1202 MapWord MapWord::EncodeAddress(Address map_address, int offset) { | |
| 1203 // Offset is the distance in live bytes from the first live object in the | |
| 1204 // same page. The offset between two objects in the same page should not | |
| 1205 // exceed the object area size of a page. | |
| 1206 ASSERT(0 <= offset && offset < Page::kObjectAreaSize); | |
| 1207 | |
| 1208 uintptr_t compact_offset = offset >> kObjectAlignmentBits; | |
| 1209 ASSERT(compact_offset < (1 << kForwardingOffsetBits)); | |
| 1210 | |
| 1211 Page* map_page = Page::FromAddress(map_address); | |
| 1212 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index); | |
| 1213 | |
| 1214 uintptr_t map_page_offset = | |
| 1215 map_page->Offset(map_address) >> kMapAlignmentBits; | |
| 1216 | |
| 1217 uintptr_t encoding = | |
| 1218 (compact_offset << kForwardingOffsetShift) | | |
| 1219 (map_page_offset << kMapPageOffsetShift) | | |
| 1220 (map_page->mc_page_index << kMapPageIndexShift); | |
| 1221 return MapWord(encoding); | |
| 1222 } | |
| 1223 | |
| 1224 | |
| 1225 Address MapWord::DecodeMapAddress(MapSpace* map_space) { | |
| 1226 int map_page_index = | |
| 1227 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift); | |
| 1228 ASSERT_MAP_PAGE_INDEX(map_page_index); | |
| 1229 | |
| 1230 int map_page_offset = static_cast<int>( | |
| 1231 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) << | |
| 1232 kMapAlignmentBits); | |
| 1233 | |
| 1234 return (map_space->PageAddress(map_page_index) + map_page_offset); | |
| 1235 } | |
| 1236 | |
| 1237 | |
| 1238 int MapWord::DecodeOffset() { | |
| 1239 // The offset field is represented in the kForwardingOffsetBits | |
| 1240 // most-significant bits. | |
| 1241 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits; | |
| 1242 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize)); | |
| 1243 return static_cast<int>(offset); | |
| 1244 } | |
| 1245 | |
| 1246 | |
| 1247 MapWord MapWord::FromEncodedAddress(Address address) { | |
| 1248 return MapWord(reinterpret_cast<uintptr_t>(address)); | |
| 1249 } | |
| 1250 | |
| 1251 | |
| 1252 Address MapWord::ToEncodedAddress() { | |
| 1253 return reinterpret_cast<Address>(value_); | |
| 1254 } | |
| 1255 | |
| 1256 | |
| 1257 #ifdef DEBUG | 1192 #ifdef DEBUG |
| 1258 void HeapObject::VerifyObjectField(int offset) { | 1193 void HeapObject::VerifyObjectField(int offset) { |
| 1259 VerifyPointer(READ_FIELD(this, offset)); | 1194 VerifyPointer(READ_FIELD(this, offset)); |
| 1260 } | 1195 } |
| 1261 | 1196 |
| 1262 void HeapObject::VerifySmiField(int offset) { | 1197 void HeapObject::VerifySmiField(int offset) { |
| 1263 ASSERT(READ_FIELD(this, offset)->IsSmi()); | 1198 ASSERT(READ_FIELD(this, offset)->IsSmi()); |
| 1264 } | 1199 } |
| 1265 #endif | 1200 #endif |
| 1266 | 1201 |
| 1267 | 1202 |
| 1268 Heap* HeapObject::GetHeap() { | 1203 Heap* HeapObject::GetHeap() { |
| 1269 // During GC, the map pointer in HeapObject is used in various ways that | 1204 Heap* heap = |
| 1270 // prevent us from retrieving Heap from the map. | 1205 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap(); |
| 1271 // Assert that we are not in GC, implement GC code in a way that it doesn't | 1206 ASSERT(heap != NULL); |
| 1272 // pull heap from the map. | 1207 ASSERT(heap->isolate() == Isolate::Current()); |
| 1273 ASSERT(HEAP->is_safe_to_read_maps()); | 1208 return heap; |
| 1274 return map()->heap(); | |
| 1275 } | 1209 } |
| 1276 | 1210 |
| 1277 | 1211 |
| 1278 Isolate* HeapObject::GetIsolate() { | 1212 Isolate* HeapObject::GetIsolate() { |
| 1279 return GetHeap()->isolate(); | 1213 return GetHeap()->isolate(); |
| 1280 } | 1214 } |
| 1281 | 1215 |
| 1282 | 1216 |
| 1283 Map* HeapObject::map() { | 1217 Map* HeapObject::map() { |
| 1284 return map_word().ToMap(); | 1218 return map_word().ToMap(); |
| 1285 } | 1219 } |
| 1286 | 1220 |
| 1287 | 1221 |
| 1288 void HeapObject::set_map(Map* value) { | 1222 void HeapObject::set_map(Map* value) { |
| 1289 set_map_word(MapWord::FromMap(value)); | 1223 set_map_word(MapWord::FromMap(value)); |
| 1224 if (value != NULL) { |
| 1225 // TODO(1600) We are passing NULL as a slot because maps can never be on |
| 1226 // evacuation candidate. |
| 1227 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value); |
| 1228 } |
| 1229 } |
| 1230 |
| 1231 |
| 1232 // Unsafe accessor omitting write barrier. |
| 1233 void HeapObject::set_map_unsafe(Map* value) { |
| 1234 set_map_word(MapWord::FromMap(value)); |
| 1290 } | 1235 } |
| 1291 | 1236 |
| 1292 | 1237 |
| 1293 MapWord HeapObject::map_word() { | 1238 MapWord HeapObject::map_word() { |
| 1294 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); | 1239 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); |
| 1295 } | 1240 } |
| 1296 | 1241 |
| 1297 | 1242 |
| 1298 void HeapObject::set_map_word(MapWord map_word) { | 1243 void HeapObject::set_map_word(MapWord map_word) { |
| 1299 // WRITE_FIELD does not invoke write barrier, but there is no need | 1244 // WRITE_FIELD does not invoke write barrier, but there is no need |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1322 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)), | 1267 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)), |
| 1323 reinterpret_cast<Object**>(FIELD_ADDR(this, end))); | 1268 reinterpret_cast<Object**>(FIELD_ADDR(this, end))); |
| 1324 } | 1269 } |
| 1325 | 1270 |
| 1326 | 1271 |
| 1327 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) { | 1272 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) { |
| 1328 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset))); | 1273 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset))); |
| 1329 } | 1274 } |
| 1330 | 1275 |
| 1331 | 1276 |
| 1332 bool HeapObject::IsMarked() { | |
| 1333 return map_word().IsMarked(); | |
| 1334 } | |
| 1335 | |
| 1336 | |
| 1337 void HeapObject::SetMark() { | |
| 1338 ASSERT(!IsMarked()); | |
| 1339 MapWord first_word = map_word(); | |
| 1340 first_word.SetMark(); | |
| 1341 set_map_word(first_word); | |
| 1342 } | |
| 1343 | |
| 1344 | |
| 1345 void HeapObject::ClearMark() { | |
| 1346 ASSERT(IsMarked()); | |
| 1347 MapWord first_word = map_word(); | |
| 1348 first_word.ClearMark(); | |
| 1349 set_map_word(first_word); | |
| 1350 } | |
| 1351 | |
| 1352 | |
| 1353 bool HeapObject::IsOverflowed() { | |
| 1354 return map_word().IsOverflowed(); | |
| 1355 } | |
| 1356 | |
| 1357 | |
| 1358 void HeapObject::SetOverflow() { | |
| 1359 MapWord first_word = map_word(); | |
| 1360 first_word.SetOverflow(); | |
| 1361 set_map_word(first_word); | |
| 1362 } | |
| 1363 | |
| 1364 | |
| 1365 void HeapObject::ClearOverflow() { | |
| 1366 ASSERT(IsOverflowed()); | |
| 1367 MapWord first_word = map_word(); | |
| 1368 first_word.ClearOverflow(); | |
| 1369 set_map_word(first_word); | |
| 1370 } | |
| 1371 | |
| 1372 | |
| 1373 double HeapNumber::value() { | 1277 double HeapNumber::value() { |
| 1374 return READ_DOUBLE_FIELD(this, kValueOffset); | 1278 return READ_DOUBLE_FIELD(this, kValueOffset); |
| 1375 } | 1279 } |
| 1376 | 1280 |
| 1377 | 1281 |
| 1378 void HeapNumber::set_value(double value) { | 1282 void HeapNumber::set_value(double value) { |
| 1379 WRITE_DOUBLE_FIELD(this, kValueOffset, value); | 1283 WRITE_DOUBLE_FIELD(this, kValueOffset, value); |
| 1380 } | 1284 } |
| 1381 | 1285 |
| 1382 | 1286 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1393 | 1297 |
| 1394 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) | 1298 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) |
| 1395 | 1299 |
| 1396 | 1300 |
| 1397 FixedArrayBase* JSObject::elements() { | 1301 FixedArrayBase* JSObject::elements() { |
| 1398 Object* array = READ_FIELD(this, kElementsOffset); | 1302 Object* array = READ_FIELD(this, kElementsOffset); |
| 1399 ASSERT(array->HasValidElements()); | 1303 ASSERT(array->HasValidElements()); |
| 1400 return static_cast<FixedArrayBase*>(array); | 1304 return static_cast<FixedArrayBase*>(array); |
| 1401 } | 1305 } |
| 1402 | 1306 |
| 1307 void JSObject::ValidateSmiOnlyElements() { |
| 1308 #if DEBUG |
| 1309 if (FLAG_smi_only_arrays && |
| 1310 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { |
| 1311 Heap* heap = GetHeap(); |
| 1312 // Don't use elements, since integrity checks will fail if there |
| 1313 // are filler pointers in the array. |
| 1314 FixedArray* fixed_array = |
| 1315 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset)); |
| 1316 Map* map = fixed_array->map(); |
| 1317 // Arrays that have been shifted in place can't be verified. |
| 1318 if (map != heap->raw_unchecked_one_pointer_filler_map() && |
| 1319 map != heap->raw_unchecked_two_pointer_filler_map() && |
| 1320 map != heap->free_space_map()) { |
| 1321 for (int i = 0; i < fixed_array->length(); i++) { |
| 1322 Object* current = fixed_array->get(i); |
| 1323 ASSERT(current->IsSmi() || current == heap->the_hole_value()); |
| 1324 } |
| 1325 } |
| 1326 } |
| 1327 #endif |
| 1328 } |
| 1329 |
| 1330 |
| 1331 MaybeObject* JSObject::EnsureCanContainNonSmiElements() { |
| 1332 #if DEBUG |
| 1333 ValidateSmiOnlyElements(); |
| 1334 #endif |
| 1335 if (FLAG_smi_only_arrays && |
| 1336 (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) { |
| 1337 Object* obj; |
| 1338 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); |
| 1339 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1340 set_map(Map::cast(obj)); |
| 1341 } |
| 1342 return this; |
| 1343 } |
| 1344 |
| 1345 |
| 1346 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, |
| 1347 uint32_t count) { |
| 1348 if (FLAG_smi_only_arrays && |
| 1349 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { |
| 1350 for (uint32_t i = 0; i < count; ++i) { |
| 1351 Object* current = *objects++; |
| 1352 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) { |
| 1353 return EnsureCanContainNonSmiElements(); |
| 1354 } |
| 1355 } |
| 1356 } |
| 1357 return this; |
| 1358 } |
| 1359 |
| 1360 |
| 1361 MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) { |
| 1362 if (FLAG_smi_only_arrays) { |
| 1363 Object** objects = reinterpret_cast<Object**>( |
| 1364 FIELD_ADDR(elements, elements->OffsetOfElementAt(0))); |
| 1365 return EnsureCanContainElements(objects, elements->length()); |
| 1366 } else { |
| 1367 return this; |
| 1368 } |
| 1369 } |
| 1370 |
| 1403 | 1371 |
| 1404 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { | 1372 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { |
| 1405 ASSERT(map()->has_fast_elements() == | 1373 ASSERT((map()->has_fast_elements() || |
| 1374 map()->has_fast_smi_only_elements()) == |
| 1406 (value->map() == GetHeap()->fixed_array_map() || | 1375 (value->map() == GetHeap()->fixed_array_map() || |
| 1407 value->map() == GetHeap()->fixed_cow_array_map())); | 1376 value->map() == GetHeap()->fixed_cow_array_map())); |
| 1408 ASSERT(map()->has_fast_double_elements() == | 1377 ASSERT(map()->has_fast_double_elements() == |
| 1409 value->IsFixedDoubleArray()); | 1378 value->IsFixedDoubleArray()); |
| 1410 ASSERT(value->HasValidElements()); | 1379 ASSERT(value->HasValidElements()); |
| 1380 #ifdef DEBUG |
| 1381 ValidateSmiOnlyElements(); |
| 1382 #endif |
| 1411 WRITE_FIELD(this, kElementsOffset, value); | 1383 WRITE_FIELD(this, kElementsOffset, value); |
| 1412 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode); | 1384 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); |
| 1413 } | 1385 } |
| 1414 | 1386 |
| 1415 | 1387 |
| 1416 void JSObject::initialize_properties() { | 1388 void JSObject::initialize_properties() { |
| 1417 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
| 1418 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); | 1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); |
| 1419 } | 1391 } |
| 1420 | 1392 |
| 1421 | 1393 |
| 1422 void JSObject::initialize_elements() { | 1394 void JSObject::initialize_elements() { |
| 1423 ASSERT(map()->has_fast_elements()); | 1395 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements()); |
| 1424 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1396 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
| 1425 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); | 1397 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); |
| 1426 } | 1398 } |
| 1427 | 1399 |
| 1428 | 1400 |
| 1429 MaybeObject* JSObject::ResetElements() { | 1401 MaybeObject* JSObject::ResetElements() { |
| 1430 Object* obj; | 1402 Object* obj; |
| 1431 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); | 1403 ElementsKind elements_kind = FLAG_smi_only_arrays |
| 1432 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1404 ? FAST_SMI_ONLY_ELEMENTS |
| 1433 } | 1405 : FAST_ELEMENTS; |
| 1406 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind); |
| 1407 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1434 set_map(Map::cast(obj)); | 1408 set_map(Map::cast(obj)); |
| 1435 initialize_elements(); | 1409 initialize_elements(); |
| 1436 return this; | 1410 return this; |
| 1437 } | 1411 } |
| 1438 | 1412 |
| 1439 | 1413 |
| 1440 ACCESSORS(Oddball, to_string, String, kToStringOffset) | 1414 ACCESSORS(Oddball, to_string, String, kToStringOffset) |
| 1441 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) | 1415 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) |
| 1442 | 1416 |
| 1443 | 1417 |
| 1444 byte Oddball::kind() { | 1418 byte Oddball::kind() { |
| 1445 return READ_BYTE_FIELD(this, kKindOffset); | 1419 return Smi::cast(READ_FIELD(this, kKindOffset))->value(); |
| 1446 } | 1420 } |
| 1447 | 1421 |
| 1448 | 1422 |
| 1449 void Oddball::set_kind(byte value) { | 1423 void Oddball::set_kind(byte value) { |
| 1450 WRITE_BYTE_FIELD(this, kKindOffset, value); | 1424 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value)); |
| 1451 } | 1425 } |
| 1452 | 1426 |
| 1453 | 1427 |
| 1454 Object* JSGlobalPropertyCell::value() { | 1428 Object* JSGlobalPropertyCell::value() { |
| 1455 return READ_FIELD(this, kValueOffset); | 1429 return READ_FIELD(this, kValueOffset); |
| 1456 } | 1430 } |
| 1457 | 1431 |
| 1458 | 1432 |
| 1459 void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) { | 1433 void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) { |
| 1460 // The write barrier is not used for global property cells. | 1434 // The write barrier is not used for global property cells. |
| 1461 ASSERT(!val->IsJSGlobalPropertyCell()); | 1435 ASSERT(!val->IsJSGlobalPropertyCell()); |
| 1462 WRITE_FIELD(this, kValueOffset, val); | 1436 WRITE_FIELD(this, kValueOffset, val); |
| 1437 GetHeap()->incremental_marking()->RecordWrite( |
| 1438 this, HeapObject::RawField(this, kValueOffset), val); |
| 1463 } | 1439 } |
| 1464 | 1440 |
| 1465 | 1441 |
| 1466 int JSObject::GetHeaderSize() { | 1442 int JSObject::GetHeaderSize() { |
| 1467 InstanceType type = map()->instance_type(); | 1443 InstanceType type = map()->instance_type(); |
| 1468 // Check for the most common kind of JavaScript object before | 1444 // Check for the most common kind of JavaScript object before |
| 1469 // falling into the generic switch. This speeds up the internal | 1445 // falling into the generic switch. This speeds up the internal |
| 1470 // field operations considerably on average. | 1446 // field operations considerably on average. |
| 1471 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize; | 1447 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize; |
| 1472 switch (type) { | 1448 switch (type) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 } | 1497 } |
| 1522 | 1498 |
| 1523 | 1499 |
| 1524 void JSObject::SetInternalField(int index, Object* value) { | 1500 void JSObject::SetInternalField(int index, Object* value) { |
| 1525 ASSERT(index < GetInternalFieldCount() && index >= 0); | 1501 ASSERT(index < GetInternalFieldCount() && index >= 0); |
| 1526 // Internal objects do follow immediately after the header, whereas in-object | 1502 // Internal objects do follow immediately after the header, whereas in-object |
| 1527 // properties are at the end of the object. Therefore there is no need | 1503 // properties are at the end of the object. Therefore there is no need |
| 1528 // to adjust the index here. | 1504 // to adjust the index here. |
| 1529 int offset = GetHeaderSize() + (kPointerSize * index); | 1505 int offset = GetHeaderSize() + (kPointerSize * index); |
| 1530 WRITE_FIELD(this, offset, value); | 1506 WRITE_FIELD(this, offset, value); |
| 1531 WRITE_BARRIER(this, offset); | 1507 WRITE_BARRIER(GetHeap(), this, offset, value); |
| 1532 } | 1508 } |
| 1533 | 1509 |
| 1534 | 1510 |
| 1535 // Access fast-case object properties at index. The use of these routines | 1511 // Access fast-case object properties at index. The use of these routines |
| 1536 // is needed to correctly distinguish between properties stored in-object and | 1512 // is needed to correctly distinguish between properties stored in-object and |
| 1537 // properties stored in the properties array. | 1513 // properties stored in the properties array. |
| 1538 Object* JSObject::FastPropertyAt(int index) { | 1514 Object* JSObject::FastPropertyAt(int index) { |
| 1539 // Adjust for the number of properties stored in the object. | 1515 // Adjust for the number of properties stored in the object. |
| 1540 index -= map()->inobject_properties(); | 1516 index -= map()->inobject_properties(); |
| 1541 if (index < 0) { | 1517 if (index < 0) { |
| 1542 int offset = map()->instance_size() + (index * kPointerSize); | 1518 int offset = map()->instance_size() + (index * kPointerSize); |
| 1543 return READ_FIELD(this, offset); | 1519 return READ_FIELD(this, offset); |
| 1544 } else { | 1520 } else { |
| 1545 ASSERT(index < properties()->length()); | 1521 ASSERT(index < properties()->length()); |
| 1546 return properties()->get(index); | 1522 return properties()->get(index); |
| 1547 } | 1523 } |
| 1548 } | 1524 } |
| 1549 | 1525 |
| 1550 | 1526 |
| 1551 Object* JSObject::FastPropertyAtPut(int index, Object* value) { | 1527 Object* JSObject::FastPropertyAtPut(int index, Object* value) { |
| 1552 // Adjust for the number of properties stored in the object. | 1528 // Adjust for the number of properties stored in the object. |
| 1553 index -= map()->inobject_properties(); | 1529 index -= map()->inobject_properties(); |
| 1554 if (index < 0) { | 1530 if (index < 0) { |
| 1555 int offset = map()->instance_size() + (index * kPointerSize); | 1531 int offset = map()->instance_size() + (index * kPointerSize); |
| 1556 WRITE_FIELD(this, offset, value); | 1532 WRITE_FIELD(this, offset, value); |
| 1557 WRITE_BARRIER(this, offset); | 1533 WRITE_BARRIER(GetHeap(), this, offset, value); |
| 1558 } else { | 1534 } else { |
| 1559 ASSERT(index < properties()->length()); | 1535 ASSERT(index < properties()->length()); |
| 1560 properties()->set(index, value); | 1536 properties()->set(index, value); |
| 1561 } | 1537 } |
| 1562 return value; | 1538 return value; |
| 1563 } | 1539 } |
| 1564 | 1540 |
| 1565 | 1541 |
| 1566 int JSObject::GetInObjectPropertyOffset(int index) { | 1542 int JSObject::GetInObjectPropertyOffset(int index) { |
| 1567 // Adjust for the number of properties stored in the object. | 1543 // Adjust for the number of properties stored in the object. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1581 | 1557 |
| 1582 | 1558 |
| 1583 Object* JSObject::InObjectPropertyAtPut(int index, | 1559 Object* JSObject::InObjectPropertyAtPut(int index, |
| 1584 Object* value, | 1560 Object* value, |
| 1585 WriteBarrierMode mode) { | 1561 WriteBarrierMode mode) { |
| 1586 // Adjust for the number of properties stored in the object. | 1562 // Adjust for the number of properties stored in the object. |
| 1587 index -= map()->inobject_properties(); | 1563 index -= map()->inobject_properties(); |
| 1588 ASSERT(index < 0); | 1564 ASSERT(index < 0); |
| 1589 int offset = map()->instance_size() + (index * kPointerSize); | 1565 int offset = map()->instance_size() + (index * kPointerSize); |
| 1590 WRITE_FIELD(this, offset, value); | 1566 WRITE_FIELD(this, offset, value); |
| 1591 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); | 1567 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); |
| 1592 return value; | 1568 return value; |
| 1593 } | 1569 } |
| 1594 | 1570 |
| 1595 | 1571 |
| 1596 | 1572 |
| 1597 void JSObject::InitializeBody(int object_size, Object* value) { | 1573 void JSObject::InitializeBody(Map* map, |
| 1598 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value)); | 1574 Object* pre_allocated_value, |
| 1599 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { | 1575 Object* filler_value) { |
| 1600 WRITE_FIELD(this, offset, value); | 1576 ASSERT(!filler_value->IsHeapObject() || |
| 1577 !GetHeap()->InNewSpace(filler_value)); |
| 1578 ASSERT(!pre_allocated_value->IsHeapObject() || |
| 1579 !GetHeap()->InNewSpace(pre_allocated_value)); |
| 1580 int size = map->instance_size(); |
| 1581 int offset = kHeaderSize; |
| 1582 if (filler_value != pre_allocated_value) { |
| 1583 int pre_allocated = map->pre_allocated_property_fields(); |
| 1584 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size); |
| 1585 for (int i = 0; i < pre_allocated; i++) { |
| 1586 WRITE_FIELD(this, offset, pre_allocated_value); |
| 1587 offset += kPointerSize; |
| 1588 } |
| 1589 } |
| 1590 while (offset < size) { |
| 1591 WRITE_FIELD(this, offset, filler_value); |
| 1592 offset += kPointerSize; |
| 1601 } | 1593 } |
| 1602 } | 1594 } |
| 1603 | 1595 |
| 1604 | 1596 |
| 1605 bool JSObject::HasFastProperties() { | 1597 bool JSObject::HasFastProperties() { |
| 1606 return !properties()->IsDictionary(); | 1598 return !properties()->IsDictionary(); |
| 1607 } | 1599 } |
| 1608 | 1600 |
| 1609 | 1601 |
| 1610 int JSObject::MaxFastProperties() { | 1602 int JSObject::MaxFastProperties() { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 int offset = kHeaderSize + index * kPointerSize; | 1668 int offset = kHeaderSize + index * kPointerSize; |
| 1677 WRITE_FIELD(this, offset, value); | 1669 WRITE_FIELD(this, offset, value); |
| 1678 } | 1670 } |
| 1679 | 1671 |
| 1680 | 1672 |
| 1681 void FixedArray::set(int index, Object* value) { | 1673 void FixedArray::set(int index, Object* value) { |
| 1682 ASSERT(map() != HEAP->fixed_cow_array_map()); | 1674 ASSERT(map() != HEAP->fixed_cow_array_map()); |
| 1683 ASSERT(index >= 0 && index < this->length()); | 1675 ASSERT(index >= 0 && index < this->length()); |
| 1684 int offset = kHeaderSize + index * kPointerSize; | 1676 int offset = kHeaderSize + index * kPointerSize; |
| 1685 WRITE_FIELD(this, offset, value); | 1677 WRITE_FIELD(this, offset, value); |
| 1686 WRITE_BARRIER(this, offset); | 1678 WRITE_BARRIER(GetHeap(), this, offset, value); |
| 1687 } | 1679 } |
| 1688 | 1680 |
| 1689 | 1681 |
| 1690 inline bool FixedDoubleArray::is_the_hole_nan(double value) { | 1682 inline bool FixedDoubleArray::is_the_hole_nan(double value) { |
| 1691 return BitCast<uint64_t, double>(value) == kHoleNanInt64; | 1683 return BitCast<uint64_t, double>(value) == kHoleNanInt64; |
| 1692 } | 1684 } |
| 1693 | 1685 |
| 1694 | 1686 |
| 1695 inline double FixedDoubleArray::hole_nan_as_double() { | 1687 inline double FixedDoubleArray::hole_nan_as_double() { |
| 1696 return BitCast<double, uint64_t>(kHoleNanInt64); | 1688 return BitCast<double, uint64_t>(kHoleNanInt64); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 int offset = kHeaderSize + old_length * kDoubleSize; | 1753 int offset = kHeaderSize + old_length * kDoubleSize; |
| 1762 for (int current = from->length(); current < length(); ++current) { | 1754 for (int current = from->length(); current < length(); ++current) { |
| 1763 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); | 1755 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); |
| 1764 offset += kDoubleSize; | 1756 offset += kDoubleSize; |
| 1765 } | 1757 } |
| 1766 } | 1758 } |
| 1767 | 1759 |
| 1768 | 1760 |
| 1769 void FixedDoubleArray::Initialize(FixedArray* from) { | 1761 void FixedDoubleArray::Initialize(FixedArray* from) { |
| 1770 int old_length = from->length(); | 1762 int old_length = from->length(); |
| 1771 ASSERT(old_length < length()); | 1763 ASSERT(old_length <= length()); |
| 1772 for (int i = 0; i < old_length; i++) { | 1764 for (int i = 0; i < old_length; i++) { |
| 1773 Object* hole_or_object = from->get(i); | 1765 Object* hole_or_object = from->get(i); |
| 1774 if (hole_or_object->IsTheHole()) { | 1766 if (hole_or_object->IsTheHole()) { |
| 1775 set_the_hole(i); | 1767 set_the_hole(i); |
| 1776 } else { | 1768 } else { |
| 1777 set(i, hole_or_object->Number()); | 1769 set(i, hole_or_object->Number()); |
| 1778 } | 1770 } |
| 1779 } | 1771 } |
| 1780 int offset = kHeaderSize + old_length * kDoubleSize; | 1772 int offset = kHeaderSize + old_length * kDoubleSize; |
| 1781 for (int current = from->length(); current < length(); ++current) { | 1773 for (int current = from->length(); current < length(); ++current) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1795 Object* key = from->KeyAt(i); | 1787 Object* key = from->KeyAt(i); |
| 1796 if (key->IsNumber()) { | 1788 if (key->IsNumber()) { |
| 1797 uint32_t entry = static_cast<uint32_t>(key->Number()); | 1789 uint32_t entry = static_cast<uint32_t>(key->Number()); |
| 1798 set(entry, from->ValueAt(i)->Number()); | 1790 set(entry, from->ValueAt(i)->Number()); |
| 1799 } | 1791 } |
| 1800 } | 1792 } |
| 1801 } | 1793 } |
| 1802 | 1794 |
| 1803 | 1795 |
| 1804 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { | 1796 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { |
| 1805 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER; | 1797 Heap* heap = GetHeap(); |
| 1798 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER; |
| 1799 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER; |
| 1806 return UPDATE_WRITE_BARRIER; | 1800 return UPDATE_WRITE_BARRIER; |
| 1807 } | 1801 } |
| 1808 | 1802 |
| 1809 | 1803 |
| 1810 void FixedArray::set(int index, | 1804 void FixedArray::set(int index, |
| 1811 Object* value, | 1805 Object* value, |
| 1812 WriteBarrierMode mode) { | 1806 WriteBarrierMode mode) { |
| 1813 ASSERT(map() != HEAP->fixed_cow_array_map()); | 1807 ASSERT(map() != HEAP->fixed_cow_array_map()); |
| 1814 ASSERT(index >= 0 && index < this->length()); | 1808 ASSERT(index >= 0 && index < this->length()); |
| 1815 int offset = kHeaderSize + index * kPointerSize; | 1809 int offset = kHeaderSize + index * kPointerSize; |
| 1816 WRITE_FIELD(this, offset, value); | 1810 WRITE_FIELD(this, offset, value); |
| 1817 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); | 1811 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); |
| 1818 } | 1812 } |
| 1819 | 1813 |
| 1820 | 1814 |
| 1821 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { | 1815 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { |
| 1822 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map()); | 1816 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map()); |
| 1823 ASSERT(index >= 0 && index < array->length()); | 1817 ASSERT(index >= 0 && index < array->length()); |
| 1824 ASSERT(!HEAP->InNewSpace(value)); | 1818 ASSERT(!HEAP->InNewSpace(value)); |
| 1825 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); | 1819 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); |
| 1820 array->GetHeap()->incremental_marking()->RecordWrite( |
| 1821 array, |
| 1822 HeapObject::RawField(array, kHeaderSize + index * kPointerSize), |
| 1823 value); |
| 1826 } | 1824 } |
| 1827 | 1825 |
| 1828 | 1826 |
| 1829 void FixedArray::set_undefined(int index) { | 1827 void FixedArray::set_undefined(int index) { |
| 1830 ASSERT(map() != HEAP->fixed_cow_array_map()); | 1828 ASSERT(map() != HEAP->fixed_cow_array_map()); |
| 1831 set_undefined(GetHeap(), index); | 1829 set_undefined(GetHeap(), index); |
| 1832 } | 1830 } |
| 1833 | 1831 |
| 1834 | 1832 |
| 1835 void FixedArray::set_undefined(Heap* heap, int index) { | 1833 void FixedArray::set_undefined(Heap* heap, int index) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 WRITE_FIELD(this, offset, value); | 1866 WRITE_FIELD(this, offset, value); |
| 1869 } | 1867 } |
| 1870 | 1868 |
| 1871 | 1869 |
| 1872 void FixedArray::set_unchecked(Heap* heap, | 1870 void FixedArray::set_unchecked(Heap* heap, |
| 1873 int index, | 1871 int index, |
| 1874 Object* value, | 1872 Object* value, |
| 1875 WriteBarrierMode mode) { | 1873 WriteBarrierMode mode) { |
| 1876 int offset = kHeaderSize + index * kPointerSize; | 1874 int offset = kHeaderSize + index * kPointerSize; |
| 1877 WRITE_FIELD(this, offset, value); | 1875 WRITE_FIELD(this, offset, value); |
| 1878 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode); | 1876 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode); |
| 1879 } | 1877 } |
| 1880 | 1878 |
| 1881 | 1879 |
| 1882 void FixedArray::set_null_unchecked(Heap* heap, int index) { | 1880 void FixedArray::set_null_unchecked(Heap* heap, int index) { |
| 1883 ASSERT(index >= 0 && index < this->length()); | 1881 ASSERT(index >= 0 && index < this->length()); |
| 1884 ASSERT(!HEAP->InNewSpace(heap->null_value())); | 1882 ASSERT(!HEAP->InNewSpace(heap->null_value())); |
| 1885 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value()); | 1883 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value()); |
| 1886 } | 1884 } |
| 1887 | 1885 |
| 1888 | 1886 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2147 CAST_ACCESSOR(JSGlobalObject) | 2145 CAST_ACCESSOR(JSGlobalObject) |
| 2148 CAST_ACCESSOR(JSBuiltinsObject) | 2146 CAST_ACCESSOR(JSBuiltinsObject) |
| 2149 CAST_ACCESSOR(Code) | 2147 CAST_ACCESSOR(Code) |
| 2150 CAST_ACCESSOR(JSArray) | 2148 CAST_ACCESSOR(JSArray) |
| 2151 CAST_ACCESSOR(JSRegExp) | 2149 CAST_ACCESSOR(JSRegExp) |
| 2152 CAST_ACCESSOR(JSProxy) | 2150 CAST_ACCESSOR(JSProxy) |
| 2153 CAST_ACCESSOR(JSFunctionProxy) | 2151 CAST_ACCESSOR(JSFunctionProxy) |
| 2154 CAST_ACCESSOR(JSWeakMap) | 2152 CAST_ACCESSOR(JSWeakMap) |
| 2155 CAST_ACCESSOR(Foreign) | 2153 CAST_ACCESSOR(Foreign) |
| 2156 CAST_ACCESSOR(ByteArray) | 2154 CAST_ACCESSOR(ByteArray) |
| 2155 CAST_ACCESSOR(FreeSpace) |
| 2157 CAST_ACCESSOR(ExternalArray) | 2156 CAST_ACCESSOR(ExternalArray) |
| 2158 CAST_ACCESSOR(ExternalByteArray) | 2157 CAST_ACCESSOR(ExternalByteArray) |
| 2159 CAST_ACCESSOR(ExternalUnsignedByteArray) | 2158 CAST_ACCESSOR(ExternalUnsignedByteArray) |
| 2160 CAST_ACCESSOR(ExternalShortArray) | 2159 CAST_ACCESSOR(ExternalShortArray) |
| 2161 CAST_ACCESSOR(ExternalUnsignedShortArray) | 2160 CAST_ACCESSOR(ExternalUnsignedShortArray) |
| 2162 CAST_ACCESSOR(ExternalIntArray) | 2161 CAST_ACCESSOR(ExternalIntArray) |
| 2163 CAST_ACCESSOR(ExternalUnsignedIntArray) | 2162 CAST_ACCESSOR(ExternalUnsignedIntArray) |
| 2164 CAST_ACCESSOR(ExternalFloatArray) | 2163 CAST_ACCESSOR(ExternalFloatArray) |
| 2165 CAST_ACCESSOR(ExternalDoubleArray) | 2164 CAST_ACCESSOR(ExternalDoubleArray) |
| 2166 CAST_ACCESSOR(ExternalPixelArray) | 2165 CAST_ACCESSOR(ExternalPixelArray) |
| 2167 CAST_ACCESSOR(Struct) | 2166 CAST_ACCESSOR(Struct) |
| 2168 | 2167 |
| 2169 | 2168 |
| 2170 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) | 2169 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
| 2171 STRUCT_LIST(MAKE_STRUCT_CAST) | 2170 STRUCT_LIST(MAKE_STRUCT_CAST) |
| 2172 #undef MAKE_STRUCT_CAST | 2171 #undef MAKE_STRUCT_CAST |
| 2173 | 2172 |
| 2174 | 2173 |
| 2175 template <typename Shape, typename Key> | 2174 template <typename Shape, typename Key> |
| 2176 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { | 2175 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { |
| 2177 ASSERT(obj->IsHashTable()); | 2176 ASSERT(obj->IsHashTable()); |
| 2178 return reinterpret_cast<HashTable*>(obj); | 2177 return reinterpret_cast<HashTable*>(obj); |
| 2179 } | 2178 } |
| 2180 | 2179 |
| 2181 | 2180 |
| 2182 SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) | 2181 SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) |
| 2182 SMI_ACCESSORS(FreeSpace, size, kSizeOffset) |
| 2183 | 2183 |
| 2184 SMI_ACCESSORS(String, length, kLengthOffset) | 2184 SMI_ACCESSORS(String, length, kLengthOffset) |
| 2185 | 2185 |
| 2186 | 2186 |
| 2187 uint32_t String::hash_field() { | 2187 uint32_t String::hash_field() { |
| 2188 return READ_UINT32_FIELD(this, kHashFieldOffset); | 2188 return READ_UINT32_FIELD(this, kHashFieldOffset); |
| 2189 } | 2189 } |
| 2190 | 2190 |
| 2191 | 2191 |
| 2192 void String::set_hash_field(uint32_t value) { | 2192 void String::set_hash_field(uint32_t value) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2329 return SizeFor(length()); | 2329 return SizeFor(length()); |
| 2330 } | 2330 } |
| 2331 | 2331 |
| 2332 | 2332 |
| 2333 String* SlicedString::parent() { | 2333 String* SlicedString::parent() { |
| 2334 return String::cast(READ_FIELD(this, kParentOffset)); | 2334 return String::cast(READ_FIELD(this, kParentOffset)); |
| 2335 } | 2335 } |
| 2336 | 2336 |
| 2337 | 2337 |
| 2338 void SlicedString::set_parent(String* parent) { | 2338 void SlicedString::set_parent(String* parent) { |
| 2339 ASSERT(parent->IsSeqString()); | 2339 ASSERT(parent->IsSeqString() || parent->IsExternalString()); |
| 2340 WRITE_FIELD(this, kParentOffset, parent); | 2340 WRITE_FIELD(this, kParentOffset, parent); |
| 2341 } | 2341 } |
| 2342 | 2342 |
| 2343 | 2343 |
| 2344 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset) | 2344 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset) |
| 2345 | 2345 |
| 2346 | 2346 |
| 2347 String* ConsString::first() { | 2347 String* ConsString::first() { |
| 2348 return String::cast(READ_FIELD(this, kFirstOffset)); | 2348 return String::cast(READ_FIELD(this, kFirstOffset)); |
| 2349 } | 2349 } |
| 2350 | 2350 |
| 2351 | 2351 |
| 2352 Object* ConsString::unchecked_first() { | 2352 Object* ConsString::unchecked_first() { |
| 2353 return READ_FIELD(this, kFirstOffset); | 2353 return READ_FIELD(this, kFirstOffset); |
| 2354 } | 2354 } |
| 2355 | 2355 |
| 2356 | 2356 |
| 2357 void ConsString::set_first(String* value, WriteBarrierMode mode) { | 2357 void ConsString::set_first(String* value, WriteBarrierMode mode) { |
| 2358 WRITE_FIELD(this, kFirstOffset, value); | 2358 WRITE_FIELD(this, kFirstOffset, value); |
| 2359 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode); | 2359 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode); |
| 2360 } | 2360 } |
| 2361 | 2361 |
| 2362 | 2362 |
| 2363 String* ConsString::second() { | 2363 String* ConsString::second() { |
| 2364 return String::cast(READ_FIELD(this, kSecondOffset)); | 2364 return String::cast(READ_FIELD(this, kSecondOffset)); |
| 2365 } | 2365 } |
| 2366 | 2366 |
| 2367 | 2367 |
| 2368 Object* ConsString::unchecked_second() { | 2368 Object* ConsString::unchecked_second() { |
| 2369 return READ_FIELD(this, kSecondOffset); | 2369 return READ_FIELD(this, kSecondOffset); |
| 2370 } | 2370 } |
| 2371 | 2371 |
| 2372 | 2372 |
| 2373 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 2373 void ConsString::set_second(String* value, WriteBarrierMode mode) { |
| 2374 WRITE_FIELD(this, kSecondOffset, value); | 2374 WRITE_FIELD(this, kSecondOffset, value); |
| 2375 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode); | 2375 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); |
| 2376 } | 2376 } |
| 2377 | 2377 |
| 2378 | 2378 |
| 2379 ExternalAsciiString::Resource* ExternalAsciiString::resource() { | 2379 const ExternalAsciiString::Resource* ExternalAsciiString::resource() { |
| 2380 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 2380 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
| 2381 } | 2381 } |
| 2382 | 2382 |
| 2383 | 2383 |
| 2384 void ExternalAsciiString::set_resource( | 2384 void ExternalAsciiString::set_resource( |
| 2385 ExternalAsciiString::Resource* resource) { | 2385 const ExternalAsciiString::Resource* resource) { |
| 2386 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; | 2386 *reinterpret_cast<const Resource**>( |
| 2387 FIELD_ADDR(this, kResourceOffset)) = resource; |
| 2387 } | 2388 } |
| 2388 | 2389 |
| 2389 | 2390 |
| 2390 ExternalTwoByteString::Resource* ExternalTwoByteString::resource() { | 2391 const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() { |
| 2391 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 2392 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
| 2392 } | 2393 } |
| 2393 | 2394 |
| 2394 | 2395 |
| 2395 void ExternalTwoByteString::set_resource( | 2396 void ExternalTwoByteString::set_resource( |
| 2396 ExternalTwoByteString::Resource* resource) { | 2397 const ExternalTwoByteString::Resource* resource) { |
| 2397 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; | 2398 *reinterpret_cast<const Resource**>( |
| 2399 FIELD_ADDR(this, kResourceOffset)) = resource; |
| 2398 } | 2400 } |
| 2399 | 2401 |
| 2400 | 2402 |
| 2401 void JSFunctionResultCache::MakeZeroSize() { | 2403 void JSFunctionResultCache::MakeZeroSize() { |
| 2402 set_finger_index(kEntriesIndex); | 2404 set_finger_index(kEntriesIndex); |
| 2403 set_size(kEntriesIndex); | 2405 set_size(kEntriesIndex); |
| 2404 } | 2406 } |
| 2405 | 2407 |
| 2406 | 2408 |
| 2407 void JSFunctionResultCache::Clear() { | 2409 void JSFunctionResultCache::Clear() { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2687 if (instance_type == FIXED_ARRAY_TYPE) { | 2689 if (instance_type == FIXED_ARRAY_TYPE) { |
| 2688 return FixedArray::BodyDescriptor::SizeOf(map, this); | 2690 return FixedArray::BodyDescriptor::SizeOf(map, this); |
| 2689 } | 2691 } |
| 2690 if (instance_type == ASCII_STRING_TYPE) { | 2692 if (instance_type == ASCII_STRING_TYPE) { |
| 2691 return SeqAsciiString::SizeFor( | 2693 return SeqAsciiString::SizeFor( |
| 2692 reinterpret_cast<SeqAsciiString*>(this)->length()); | 2694 reinterpret_cast<SeqAsciiString*>(this)->length()); |
| 2693 } | 2695 } |
| 2694 if (instance_type == BYTE_ARRAY_TYPE) { | 2696 if (instance_type == BYTE_ARRAY_TYPE) { |
| 2695 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); | 2697 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); |
| 2696 } | 2698 } |
| 2699 if (instance_type == FREE_SPACE_TYPE) { |
| 2700 return reinterpret_cast<FreeSpace*>(this)->size(); |
| 2701 } |
| 2697 if (instance_type == STRING_TYPE) { | 2702 if (instance_type == STRING_TYPE) { |
| 2698 return SeqTwoByteString::SizeFor( | 2703 return SeqTwoByteString::SizeFor( |
| 2699 reinterpret_cast<SeqTwoByteString*>(this)->length()); | 2704 reinterpret_cast<SeqTwoByteString*>(this)->length()); |
| 2700 } | 2705 } |
| 2701 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { | 2706 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { |
| 2702 return FixedDoubleArray::SizeFor( | 2707 return FixedDoubleArray::SizeFor( |
| 2703 reinterpret_cast<FixedDoubleArray*>(this)->length()); | 2708 reinterpret_cast<FixedDoubleArray*>(this)->length()); |
| 2704 } | 2709 } |
| 2705 ASSERT(instance_type == CODE_TYPE); | 2710 ASSERT(instance_type == CODE_TYPE); |
| 2706 return reinterpret_cast<Code*>(this)->CodeSize(); | 2711 return reinterpret_cast<Code*>(this)->CodeSize(); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2848 bool Map::is_shared() { | 2853 bool Map::is_shared() { |
| 2849 return ((1 << kIsShared) & bit_field3()) != 0; | 2854 return ((1 << kIsShared) & bit_field3()) != 0; |
| 2850 } | 2855 } |
| 2851 | 2856 |
| 2852 | 2857 |
| 2853 JSFunction* Map::unchecked_constructor() { | 2858 JSFunction* Map::unchecked_constructor() { |
| 2854 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); | 2859 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); |
| 2855 } | 2860 } |
| 2856 | 2861 |
| 2857 | 2862 |
| 2858 FixedArray* Map::unchecked_prototype_transitions() { | |
| 2859 return reinterpret_cast<FixedArray*>( | |
| 2860 READ_FIELD(this, kPrototypeTransitionsOffset)); | |
| 2861 } | |
| 2862 | |
| 2863 | |
| 2864 Code::Flags Code::flags() { | 2863 Code::Flags Code::flags() { |
| 2865 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); | 2864 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); |
| 2866 } | 2865 } |
| 2867 | 2866 |
| 2868 | 2867 |
| 2869 void Code::set_flags(Code::Flags flags) { | 2868 void Code::set_flags(Code::Flags flags) { |
| 2870 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); | 2869 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); |
| 2871 // Make sure that all call stubs have an arguments count. | 2870 // Make sure that all call stubs have an arguments count. |
| 2872 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && | 2871 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && |
| 2873 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || | 2872 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2925 ASSERT(kind() == STUB || | 2924 ASSERT(kind() == STUB || |
| 2926 kind() == UNARY_OP_IC || | 2925 kind() == UNARY_OP_IC || |
| 2927 kind() == BINARY_OP_IC || | 2926 kind() == BINARY_OP_IC || |
| 2928 kind() == COMPARE_IC || | 2927 kind() == COMPARE_IC || |
| 2929 kind() == TO_BOOLEAN_IC); | 2928 kind() == TO_BOOLEAN_IC); |
| 2930 ASSERT(0 <= major && major < 256); | 2929 ASSERT(0 <= major && major < 256); |
| 2931 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major); | 2930 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major); |
| 2932 } | 2931 } |
| 2933 | 2932 |
| 2934 | 2933 |
| 2934 bool Code::is_pregenerated() { |
| 2935 return kind() == STUB && IsPregeneratedField::decode(flags()); |
| 2936 } |
| 2937 |
| 2938 |
| 2939 void Code::set_is_pregenerated(bool value) { |
| 2940 ASSERT(kind() == STUB); |
| 2941 Flags f = flags(); |
| 2942 f = static_cast<Flags>(IsPregeneratedField::update(f, value)); |
| 2943 set_flags(f); |
| 2944 } |
| 2945 |
| 2946 |
| 2935 bool Code::optimizable() { | 2947 bool Code::optimizable() { |
| 2936 ASSERT(kind() == FUNCTION); | 2948 ASSERT(kind() == FUNCTION); |
| 2937 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1; | 2949 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1; |
| 2938 } | 2950 } |
| 2939 | 2951 |
| 2940 | 2952 |
| 2941 void Code::set_optimizable(bool value) { | 2953 void Code::set_optimizable(bool value) { |
| 2942 ASSERT(kind() == FUNCTION); | 2954 ASSERT(kind() == FUNCTION); |
| 2943 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0); | 2955 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0); |
| 2944 } | 2956 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3090 ASSERT(is_to_boolean_ic_stub()); | 3102 ASSERT(is_to_boolean_ic_stub()); |
| 3091 return READ_BYTE_FIELD(this, kToBooleanTypeOffset); | 3103 return READ_BYTE_FIELD(this, kToBooleanTypeOffset); |
| 3092 } | 3104 } |
| 3093 | 3105 |
| 3094 | 3106 |
| 3095 void Code::set_to_boolean_state(byte value) { | 3107 void Code::set_to_boolean_state(byte value) { |
| 3096 ASSERT(is_to_boolean_ic_stub()); | 3108 ASSERT(is_to_boolean_ic_stub()); |
| 3097 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value); | 3109 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value); |
| 3098 } | 3110 } |
| 3099 | 3111 |
| 3112 |
| 3113 bool Code::has_function_cache() { |
| 3114 ASSERT(kind() == STUB); |
| 3115 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0; |
| 3116 } |
| 3117 |
| 3118 |
| 3119 void Code::set_has_function_cache(bool flag) { |
| 3120 ASSERT(kind() == STUB); |
| 3121 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag); |
| 3122 } |
| 3123 |
| 3124 |
| 3100 bool Code::is_inline_cache_stub() { | 3125 bool Code::is_inline_cache_stub() { |
| 3101 Kind kind = this->kind(); | 3126 Kind kind = this->kind(); |
| 3102 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND; | 3127 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND; |
| 3103 } | 3128 } |
| 3104 | 3129 |
| 3105 | 3130 |
| 3106 Code::Flags Code::ComputeFlags(Kind kind, | 3131 Code::Flags Code::ComputeFlags(Kind kind, |
| 3107 InlineCacheState ic_state, | 3132 InlineCacheState ic_state, |
| 3108 ExtraICState extra_ic_state, | 3133 ExtraICState extra_ic_state, |
| 3109 PropertyType type, | 3134 PropertyType type, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize); | 3200 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize); |
| 3176 // GetCodeFromTargetAddress might be called when marking objects during mark | 3201 // GetCodeFromTargetAddress might be called when marking objects during mark |
| 3177 // sweep. reinterpret_cast is therefore used instead of the more appropriate | 3202 // sweep. reinterpret_cast is therefore used instead of the more appropriate |
| 3178 // Code::cast. Code::cast does not work when the object's map is | 3203 // Code::cast. Code::cast does not work when the object's map is |
| 3179 // marked. | 3204 // marked. |
| 3180 Code* result = reinterpret_cast<Code*>(code); | 3205 Code* result = reinterpret_cast<Code*>(code); |
| 3181 return result; | 3206 return result; |
| 3182 } | 3207 } |
| 3183 | 3208 |
| 3184 | 3209 |
| 3185 Isolate* Map::isolate() { | |
| 3186 return heap()->isolate(); | |
| 3187 } | |
| 3188 | |
| 3189 | |
| 3190 Heap* Map::heap() { | |
| 3191 // NOTE: address() helper is not used to save one instruction. | |
| 3192 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_; | |
| 3193 ASSERT(heap != NULL); | |
| 3194 ASSERT(heap->isolate() == Isolate::Current()); | |
| 3195 return heap; | |
| 3196 } | |
| 3197 | |
| 3198 | |
| 3199 Heap* Code::heap() { | |
| 3200 // NOTE: address() helper is not used to save one instruction. | |
| 3201 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_; | |
| 3202 ASSERT(heap != NULL); | |
| 3203 ASSERT(heap->isolate() == Isolate::Current()); | |
| 3204 return heap; | |
| 3205 } | |
| 3206 | |
| 3207 | |
| 3208 Isolate* Code::isolate() { | |
| 3209 return heap()->isolate(); | |
| 3210 } | |
| 3211 | |
| 3212 | |
| 3213 Heap* JSGlobalPropertyCell::heap() { | |
| 3214 // NOTE: address() helper is not used to save one instruction. | |
| 3215 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_; | |
| 3216 ASSERT(heap != NULL); | |
| 3217 ASSERT(heap->isolate() == Isolate::Current()); | |
| 3218 return heap; | |
| 3219 } | |
| 3220 | |
| 3221 | |
| 3222 Isolate* JSGlobalPropertyCell::isolate() { | |
| 3223 return heap()->isolate(); | |
| 3224 } | |
| 3225 | |
| 3226 | |
| 3227 Object* Code::GetObjectFromEntryAddress(Address location_of_address) { | 3210 Object* Code::GetObjectFromEntryAddress(Address location_of_address) { |
| 3228 return HeapObject:: | 3211 return HeapObject:: |
| 3229 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize); | 3212 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize); |
| 3230 } | 3213 } |
| 3231 | 3214 |
| 3232 | 3215 |
| 3233 Object* Map::prototype() { | 3216 Object* Map::prototype() { |
| 3234 return READ_FIELD(this, kPrototypeOffset); | 3217 return READ_FIELD(this, kPrototypeOffset); |
| 3235 } | 3218 } |
| 3236 | 3219 |
| 3237 | 3220 |
| 3238 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3221 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
| 3239 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3222 ASSERT(value->IsNull() || value->IsJSReceiver()); |
| 3240 WRITE_FIELD(this, kPrototypeOffset, value); | 3223 WRITE_FIELD(this, kPrototypeOffset, value); |
| 3241 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode); | 3224 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
| 3242 } | |
| 3243 | |
| 3244 | |
| 3245 MaybeObject* Map::GetFastElementsMap() { | |
| 3246 if (has_fast_elements()) return this; | |
| 3247 Object* obj; | |
| 3248 { MaybeObject* maybe_obj = CopyDropTransitions(); | |
| 3249 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 3250 } | |
| 3251 Map* new_map = Map::cast(obj); | |
| 3252 new_map->set_elements_kind(FAST_ELEMENTS); | |
| 3253 isolate()->counters()->map_to_fast_elements()->Increment(); | |
| 3254 return new_map; | |
| 3255 } | |
| 3256 | |
| 3257 | |
| 3258 MaybeObject* Map::GetFastDoubleElementsMap() { | |
| 3259 if (has_fast_double_elements()) return this; | |
| 3260 Object* obj; | |
| 3261 { MaybeObject* maybe_obj = CopyDropTransitions(); | |
| 3262 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 3263 } | |
| 3264 Map* new_map = Map::cast(obj); | |
| 3265 new_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); | |
| 3266 isolate()->counters()->map_to_fast_double_elements()->Increment(); | |
| 3267 return new_map; | |
| 3268 } | |
| 3269 | |
| 3270 | |
| 3271 MaybeObject* Map::GetSlowElementsMap() { | |
| 3272 if (!has_fast_elements() && !has_fast_double_elements()) return this; | |
| 3273 Object* obj; | |
| 3274 { MaybeObject* maybe_obj = CopyDropTransitions(); | |
| 3275 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 3276 } | |
| 3277 Map* new_map = Map::cast(obj); | |
| 3278 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | |
| 3279 isolate()->counters()->map_to_slow_elements()->Increment(); | |
| 3280 return new_map; | |
| 3281 } | 3225 } |
| 3282 | 3226 |
| 3283 | 3227 |
| 3284 DescriptorArray* Map::instance_descriptors() { | 3228 DescriptorArray* Map::instance_descriptors() { |
| 3285 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); | 3229 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); |
| 3286 if (object->IsSmi()) { | 3230 if (object->IsSmi()) { |
| 3287 return HEAP->empty_descriptor_array(); | 3231 return HEAP->empty_descriptor_array(); |
| 3288 } else { | 3232 } else { |
| 3289 return DescriptorArray::cast(object); | 3233 return DescriptorArray::cast(object); |
| 3290 } | 3234 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3305 kInstanceDescriptorsOrBitField3Offset, | 3249 kInstanceDescriptorsOrBitField3Offset, |
| 3306 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage())); | 3250 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage())); |
| 3307 } | 3251 } |
| 3308 } | 3252 } |
| 3309 | 3253 |
| 3310 | 3254 |
| 3311 void Map::set_instance_descriptors(DescriptorArray* value, | 3255 void Map::set_instance_descriptors(DescriptorArray* value, |
| 3312 WriteBarrierMode mode) { | 3256 WriteBarrierMode mode) { |
| 3313 Object* object = READ_FIELD(this, | 3257 Object* object = READ_FIELD(this, |
| 3314 kInstanceDescriptorsOrBitField3Offset); | 3258 kInstanceDescriptorsOrBitField3Offset); |
| 3315 if (value == isolate()->heap()->empty_descriptor_array()) { | 3259 Heap* heap = GetHeap(); |
| 3260 if (value == heap->empty_descriptor_array()) { |
| 3316 clear_instance_descriptors(); | 3261 clear_instance_descriptors(); |
| 3317 return; | 3262 return; |
| 3318 } else { | 3263 } else { |
| 3319 if (object->IsSmi()) { | 3264 if (object->IsSmi()) { |
| 3320 value->set_bit_field3_storage(Smi::cast(object)->value()); | 3265 value->set_bit_field3_storage(Smi::cast(object)->value()); |
| 3321 } else { | 3266 } else { |
| 3322 value->set_bit_field3_storage( | 3267 value->set_bit_field3_storage( |
| 3323 DescriptorArray::cast(object)->bit_field3_storage()); | 3268 DescriptorArray::cast(object)->bit_field3_storage()); |
| 3324 } | 3269 } |
| 3325 } | 3270 } |
| 3326 ASSERT(!is_shared()); | 3271 ASSERT(!is_shared()); |
| 3327 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); | 3272 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); |
| 3328 CONDITIONAL_WRITE_BARRIER(GetHeap(), | 3273 CONDITIONAL_WRITE_BARRIER( |
| 3329 this, | 3274 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode); |
| 3330 kInstanceDescriptorsOrBitField3Offset, | |
| 3331 mode); | |
| 3332 } | 3275 } |
| 3333 | 3276 |
| 3334 | 3277 |
| 3335 int Map::bit_field3() { | 3278 int Map::bit_field3() { |
| 3336 Object* object = READ_FIELD(this, | 3279 Object* object = READ_FIELD(this, |
| 3337 kInstanceDescriptorsOrBitField3Offset); | 3280 kInstanceDescriptorsOrBitField3Offset); |
| 3338 if (object->IsSmi()) { | 3281 if (object->IsSmi()) { |
| 3339 return Smi::cast(object)->value(); | 3282 return Smi::cast(object)->value(); |
| 3340 } else { | 3283 } else { |
| 3341 return DescriptorArray::cast(object)->bit_field3_storage(); | 3284 return DescriptorArray::cast(object)->bit_field3_storage(); |
| 3342 } | 3285 } |
| 3343 } | 3286 } |
| 3344 | 3287 |
| 3345 | 3288 |
| 3346 void Map::set_bit_field3(int value) { | 3289 void Map::set_bit_field3(int value) { |
| 3347 ASSERT(Smi::IsValid(value)); | 3290 ASSERT(Smi::IsValid(value)); |
| 3348 Object* object = READ_FIELD(this, | 3291 Object* object = READ_FIELD(this, |
| 3349 kInstanceDescriptorsOrBitField3Offset); | 3292 kInstanceDescriptorsOrBitField3Offset); |
| 3350 if (object->IsSmi()) { | 3293 if (object->IsSmi()) { |
| 3351 WRITE_FIELD(this, | 3294 WRITE_FIELD(this, |
| 3352 kInstanceDescriptorsOrBitField3Offset, | 3295 kInstanceDescriptorsOrBitField3Offset, |
| 3353 Smi::FromInt(value)); | 3296 Smi::FromInt(value)); |
| 3354 } else { | 3297 } else { |
| 3355 DescriptorArray::cast(object)->set_bit_field3_storage(value); | 3298 DescriptorArray::cast(object)->set_bit_field3_storage(value); |
| 3356 } | 3299 } |
| 3357 } | 3300 } |
| 3358 | 3301 |
| 3359 | 3302 |
| 3303 FixedArray* Map::unchecked_prototype_transitions() { |
| 3304 return reinterpret_cast<FixedArray*>( |
| 3305 READ_FIELD(this, kPrototypeTransitionsOffset)); |
| 3306 } |
| 3307 |
| 3308 |
| 3360 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) | 3309 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) |
| 3361 ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset) | 3310 ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset) |
| 3362 ACCESSORS(Map, constructor, Object, kConstructorOffset) | 3311 ACCESSORS(Map, constructor, Object, kConstructorOffset) |
| 3363 | 3312 |
| 3364 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) | 3313 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) |
| 3365 ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset) | 3314 ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset) |
| 3366 ACCESSORS_GCSAFE(JSFunction, next_function_link, Object, | 3315 ACCESSORS(JSFunction, |
| 3367 kNextFunctionLinkOffset) | 3316 next_function_link, |
| 3317 Object, |
| 3318 kNextFunctionLinkOffset) |
| 3368 | 3319 |
| 3369 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset) | 3320 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset) |
| 3370 ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset) | 3321 ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset) |
| 3371 ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset) | 3322 ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset) |
| 3372 | 3323 |
| 3373 ACCESSORS(JSGlobalProxy, context, Object, kContextOffset) | 3324 ACCESSORS(JSGlobalProxy, context, Object, kContextOffset) |
| 3374 | 3325 |
| 3375 ACCESSORS(AccessorInfo, getter, Object, kGetterOffset) | 3326 ACCESSORS(AccessorInfo, getter, Object, kGetterOffset) |
| 3376 ACCESSORS(AccessorInfo, setter, Object, kSetterOffset) | 3327 ACCESSORS(AccessorInfo, setter, Object, kSetterOffset) |
| 3377 ACCESSORS(AccessorInfo, data, Object, kDataOffset) | 3328 ACCESSORS(AccessorInfo, data, Object, kDataOffset) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3446 ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex) | 3397 ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex) |
| 3447 ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex) | 3398 ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex) |
| 3448 | 3399 |
| 3449 ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex) | 3400 ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex) |
| 3450 ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex) | 3401 ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex) |
| 3451 ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex) | 3402 ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex) |
| 3452 ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex) | 3403 ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex) |
| 3453 #endif | 3404 #endif |
| 3454 | 3405 |
| 3455 ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset) | 3406 ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset) |
| 3456 ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset) | 3407 ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset) |
| 3457 ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset) | 3408 ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset) |
| 3458 ACCESSORS(SharedFunctionInfo, instance_class_name, Object, | 3409 ACCESSORS(SharedFunctionInfo, instance_class_name, Object, |
| 3459 kInstanceClassNameOffset) | 3410 kInstanceClassNameOffset) |
| 3460 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset) | 3411 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset) |
| 3461 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset) | 3412 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset) |
| 3462 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset) | 3413 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset) |
| 3463 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset) | 3414 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset) |
| 3464 ACCESSORS(SharedFunctionInfo, this_property_assignments, Object, | 3415 ACCESSORS(SharedFunctionInfo, this_property_assignments, Object, |
| 3465 kThisPropertyAssignmentsOffset) | 3416 kThisPropertyAssignmentsOffset) |
| 3466 | 3417 |
| 3467 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype, | 3418 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype, |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3653 } | 3604 } |
| 3654 | 3605 |
| 3655 | 3606 |
| 3656 Code* SharedFunctionInfo::unchecked_code() { | 3607 Code* SharedFunctionInfo::unchecked_code() { |
| 3657 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset)); | 3608 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset)); |
| 3658 } | 3609 } |
| 3659 | 3610 |
| 3660 | 3611 |
| 3661 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) { | 3612 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) { |
| 3662 WRITE_FIELD(this, kCodeOffset, value); | 3613 WRITE_FIELD(this, kCodeOffset, value); |
| 3663 ASSERT(!Isolate::Current()->heap()->InNewSpace(value)); | 3614 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode); |
| 3664 } | 3615 } |
| 3665 | 3616 |
| 3666 | 3617 |
| 3667 SerializedScopeInfo* SharedFunctionInfo::scope_info() { | 3618 SerializedScopeInfo* SharedFunctionInfo::scope_info() { |
| 3668 return reinterpret_cast<SerializedScopeInfo*>( | 3619 return reinterpret_cast<SerializedScopeInfo*>( |
| 3669 READ_FIELD(this, kScopeInfoOffset)); | 3620 READ_FIELD(this, kScopeInfoOffset)); |
| 3670 } | 3621 } |
| 3671 | 3622 |
| 3672 | 3623 |
| 3673 void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value, | 3624 void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value, |
| 3674 WriteBarrierMode mode) { | 3625 WriteBarrierMode mode) { |
| 3675 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value)); | 3626 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value)); |
| 3676 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode); | 3627 CONDITIONAL_WRITE_BARRIER(GetHeap(), |
| 3628 this, |
| 3629 kScopeInfoOffset, |
| 3630 reinterpret_cast<Object*>(value), |
| 3631 mode); |
| 3677 } | 3632 } |
| 3678 | 3633 |
| 3679 | 3634 |
| 3680 Smi* SharedFunctionInfo::deopt_counter() { | 3635 Smi* SharedFunctionInfo::deopt_counter() { |
| 3681 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset)); | 3636 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset)); |
| 3682 } | 3637 } |
| 3683 | 3638 |
| 3684 | 3639 |
| 3685 void SharedFunctionInfo::set_deopt_counter(Smi* value) { | 3640 void SharedFunctionInfo::set_deopt_counter(Smi* value) { |
| 3686 WRITE_FIELD(this, kDeoptCounterOffset, value); | 3641 WRITE_FIELD(this, kDeoptCounterOffset, value); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3763 } | 3718 } |
| 3764 | 3719 |
| 3765 | 3720 |
| 3766 Code* JSFunction::unchecked_code() { | 3721 Code* JSFunction::unchecked_code() { |
| 3767 return reinterpret_cast<Code*>( | 3722 return reinterpret_cast<Code*>( |
| 3768 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset))); | 3723 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset))); |
| 3769 } | 3724 } |
| 3770 | 3725 |
| 3771 | 3726 |
| 3772 void JSFunction::set_code(Code* value) { | 3727 void JSFunction::set_code(Code* value) { |
| 3773 // Skip the write barrier because code is never in new space. | |
| 3774 ASSERT(!HEAP->InNewSpace(value)); | 3728 ASSERT(!HEAP->InNewSpace(value)); |
| 3775 Address entry = value->entry(); | 3729 Address entry = value->entry(); |
| 3776 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry)); | 3730 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry)); |
| 3731 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry( |
| 3732 this, |
| 3733 HeapObject::RawField(this, kCodeEntryOffset), |
| 3734 value); |
| 3777 } | 3735 } |
| 3778 | 3736 |
| 3779 | 3737 |
| 3780 void JSFunction::ReplaceCode(Code* code) { | 3738 void JSFunction::ReplaceCode(Code* code) { |
| 3781 bool was_optimized = IsOptimized(); | 3739 bool was_optimized = IsOptimized(); |
| 3782 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION; | 3740 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION; |
| 3783 | 3741 |
| 3784 set_code(code); | 3742 set_code(code); |
| 3785 | 3743 |
| 3786 // Add/remove the function from the list of optimized functions for this | 3744 // Add/remove the function from the list of optimized functions for this |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3806 | 3764 |
| 3807 SharedFunctionInfo* JSFunction::unchecked_shared() { | 3765 SharedFunctionInfo* JSFunction::unchecked_shared() { |
| 3808 return reinterpret_cast<SharedFunctionInfo*>( | 3766 return reinterpret_cast<SharedFunctionInfo*>( |
| 3809 READ_FIELD(this, kSharedFunctionInfoOffset)); | 3767 READ_FIELD(this, kSharedFunctionInfoOffset)); |
| 3810 } | 3768 } |
| 3811 | 3769 |
| 3812 | 3770 |
| 3813 void JSFunction::set_context(Object* value) { | 3771 void JSFunction::set_context(Object* value) { |
| 3814 ASSERT(value->IsUndefined() || value->IsContext()); | 3772 ASSERT(value->IsUndefined() || value->IsContext()); |
| 3815 WRITE_FIELD(this, kContextOffset, value); | 3773 WRITE_FIELD(this, kContextOffset, value); |
| 3816 WRITE_BARRIER(this, kContextOffset); | 3774 WRITE_BARRIER(GetHeap(), this, kContextOffset, value); |
| 3817 } | 3775 } |
| 3818 | 3776 |
| 3819 ACCESSORS(JSFunction, prototype_or_initial_map, Object, | 3777 ACCESSORS(JSFunction, prototype_or_initial_map, Object, |
| 3820 kPrototypeOrInitialMapOffset) | 3778 kPrototypeOrInitialMapOffset) |
| 3821 | 3779 |
| 3822 | 3780 |
| 3823 Map* JSFunction::initial_map() { | 3781 Map* JSFunction::initial_map() { |
| 3824 return Map::cast(prototype_or_initial_map()); | 3782 return Map::cast(prototype_or_initial_map()); |
| 3825 } | 3783 } |
| 3826 | 3784 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3880 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) { | 3838 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) { |
| 3881 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3839 ASSERT(id < kJSBuiltinsCount); // id is unsigned. |
| 3882 return READ_FIELD(this, OffsetOfFunctionWithId(id)); | 3840 return READ_FIELD(this, OffsetOfFunctionWithId(id)); |
| 3883 } | 3841 } |
| 3884 | 3842 |
| 3885 | 3843 |
| 3886 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, | 3844 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, |
| 3887 Object* value) { | 3845 Object* value) { |
| 3888 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3846 ASSERT(id < kJSBuiltinsCount); // id is unsigned. |
| 3889 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value); | 3847 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value); |
| 3890 WRITE_BARRIER(this, OffsetOfFunctionWithId(id)); | 3848 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value); |
| 3891 } | 3849 } |
| 3892 | 3850 |
| 3893 | 3851 |
| 3894 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) { | 3852 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) { |
| 3895 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3853 ASSERT(id < kJSBuiltinsCount); // id is unsigned. |
| 3896 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id))); | 3854 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id))); |
| 3897 } | 3855 } |
| 3898 | 3856 |
| 3899 | 3857 |
| 3900 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, | 3858 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, |
| 3901 Code* value) { | 3859 Code* value) { |
| 3902 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3860 ASSERT(id < kJSBuiltinsCount); // id is unsigned. |
| 3903 WRITE_FIELD(this, OffsetOfCodeWithId(id), value); | 3861 WRITE_FIELD(this, OffsetOfCodeWithId(id), value); |
| 3904 ASSERT(!HEAP->InNewSpace(value)); | 3862 ASSERT(!HEAP->InNewSpace(value)); |
| 3905 } | 3863 } |
| 3906 | 3864 |
| 3907 | 3865 |
| 3908 ACCESSORS(JSProxy, handler, Object, kHandlerOffset) | 3866 ACCESSORS(JSProxy, handler, Object, kHandlerOffset) |
| 3867 ACCESSORS(JSProxy, hash, Object, kHashOffset) |
| 3909 ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset) | 3868 ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset) |
| 3910 ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset) | 3869 ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset) |
| 3911 | 3870 |
| 3912 | 3871 |
| 3913 void JSProxy::InitializeBody(int object_size, Object* value) { | 3872 void JSProxy::InitializeBody(int object_size, Object* value) { |
| 3914 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value)); | 3873 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value)); |
| 3915 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { | 3874 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { |
| 3916 WRITE_FIELD(this, offset, value); | 3875 WRITE_FIELD(this, offset, value); |
| 3917 } | 3876 } |
| 3918 } | 3877 } |
| 3919 | 3878 |
| 3920 | 3879 |
| 3921 ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset) | 3880 ACCESSORS(JSWeakMap, table, Object, kTableOffset) |
| 3922 ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset) | 3881 ACCESSORS(JSWeakMap, next, Object, kNextOffset) |
| 3923 | 3882 |
| 3924 | 3883 |
| 3925 ObjectHashTable* JSWeakMap::unchecked_table() { | 3884 ObjectHashTable* JSWeakMap::unchecked_table() { |
| 3926 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset)); | 3885 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset)); |
| 3927 } | 3886 } |
| 3928 | 3887 |
| 3929 | 3888 |
| 3930 Address Foreign::address() { | 3889 Address Foreign::address() { |
| 3931 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset)); | 3890 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset)); |
| 3932 } | 3891 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4004 int Code::relocation_size() { | 3963 int Code::relocation_size() { |
| 4005 return unchecked_relocation_info()->length(); | 3964 return unchecked_relocation_info()->length(); |
| 4006 } | 3965 } |
| 4007 | 3966 |
| 4008 | 3967 |
| 4009 byte* Code::entry() { | 3968 byte* Code::entry() { |
| 4010 return instruction_start(); | 3969 return instruction_start(); |
| 4011 } | 3970 } |
| 4012 | 3971 |
| 4013 | 3972 |
| 4014 bool Code::contains(byte* pc) { | 3973 bool Code::contains(byte* inner_pointer) { |
| 4015 return (instruction_start() <= pc) && | 3974 return (address() <= inner_pointer) && (inner_pointer <= address() + Size()); |
| 4016 (pc <= instruction_start() + instruction_size()); | |
| 4017 } | 3975 } |
| 4018 | 3976 |
| 4019 | 3977 |
| 4020 ACCESSORS(JSArray, length, Object, kLengthOffset) | 3978 ACCESSORS(JSArray, length, Object, kLengthOffset) |
| 4021 | 3979 |
| 4022 | 3980 |
| 4023 ACCESSORS(JSRegExp, data, Object, kDataOffset) | 3981 ACCESSORS(JSRegExp, data, Object, kDataOffset) |
| 4024 | 3982 |
| 4025 | 3983 |
| 4026 JSRegExp::Type JSRegExp::TypeTag() { | 3984 JSRegExp::Type JSRegExp::TypeTag() { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4085 FixedArray::cast(data())->set(index, value); | 4043 FixedArray::cast(data())->set(index, value); |
| 4086 } | 4044 } |
| 4087 | 4045 |
| 4088 | 4046 |
| 4089 void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) { | 4047 void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) { |
| 4090 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. | 4048 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. |
| 4091 FixedArray* fa = reinterpret_cast<FixedArray*>(data()); | 4049 FixedArray* fa = reinterpret_cast<FixedArray*>(data()); |
| 4092 if (value->IsSmi()) { | 4050 if (value->IsSmi()) { |
| 4093 fa->set_unchecked(index, Smi::cast(value)); | 4051 fa->set_unchecked(index, Smi::cast(value)); |
| 4094 } else { | 4052 } else { |
| 4053 // We only do this during GC, so we don't need to notify the write barrier. |
| 4095 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER); | 4054 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER); |
| 4096 } | 4055 } |
| 4097 } | 4056 } |
| 4098 | 4057 |
| 4099 | 4058 |
| 4100 ElementsKind JSObject::GetElementsKind() { | 4059 ElementsKind JSObject::GetElementsKind() { |
| 4101 ElementsKind kind = map()->elements_kind(); | 4060 ElementsKind kind = map()->elements_kind(); |
| 4102 ASSERT((kind == FAST_ELEMENTS && | 4061 #if DEBUG |
| 4103 (elements()->map() == GetHeap()->fixed_array_map() || | 4062 FixedArrayBase* fixed_array = |
| 4104 elements()->map() == GetHeap()->fixed_cow_array_map())) || | 4063 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); |
| 4064 Map* map = fixed_array->map(); |
| 4065 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && |
| 4066 (map == GetHeap()->fixed_array_map() || |
| 4067 map == GetHeap()->fixed_cow_array_map())) || |
| 4105 (kind == FAST_DOUBLE_ELEMENTS && | 4068 (kind == FAST_DOUBLE_ELEMENTS && |
| 4106 elements()->IsFixedDoubleArray()) || | 4069 fixed_array->IsFixedDoubleArray()) || |
| 4107 (kind == DICTIONARY_ELEMENTS && | 4070 (kind == DICTIONARY_ELEMENTS && |
| 4108 elements()->IsFixedArray() && | 4071 fixed_array->IsFixedArray() && |
| 4109 elements()->IsDictionary()) || | 4072 fixed_array->IsDictionary()) || |
| 4110 (kind > DICTIONARY_ELEMENTS)); | 4073 (kind > DICTIONARY_ELEMENTS)); |
| 4074 #endif |
| 4111 return kind; | 4075 return kind; |
| 4112 } | 4076 } |
| 4113 | 4077 |
| 4114 | 4078 |
| 4115 ElementsAccessor* JSObject::GetElementsAccessor() { | 4079 ElementsAccessor* JSObject::GetElementsAccessor() { |
| 4116 return ElementsAccessor::ForKind(GetElementsKind()); | 4080 return ElementsAccessor::ForKind(GetElementsKind()); |
| 4117 } | 4081 } |
| 4118 | 4082 |
| 4119 | 4083 |
| 4120 bool JSObject::HasFastElements() { | 4084 bool JSObject::HasFastElements() { |
| 4121 return GetElementsKind() == FAST_ELEMENTS; | 4085 return GetElementsKind() == FAST_ELEMENTS; |
| 4122 } | 4086 } |
| 4123 | 4087 |
| 4124 | 4088 |
| 4089 bool JSObject::HasFastSmiOnlyElements() { |
| 4090 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; |
| 4091 } |
| 4092 |
| 4093 |
| 4094 bool JSObject::HasFastTypeElements() { |
| 4095 ElementsKind elements_kind = GetElementsKind(); |
| 4096 return elements_kind == FAST_SMI_ONLY_ELEMENTS || |
| 4097 elements_kind == FAST_ELEMENTS; |
| 4098 } |
| 4099 |
| 4100 |
| 4125 bool JSObject::HasFastDoubleElements() { | 4101 bool JSObject::HasFastDoubleElements() { |
| 4126 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; | 4102 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; |
| 4127 } | 4103 } |
| 4128 | 4104 |
| 4129 | 4105 |
| 4130 bool JSObject::HasDictionaryElements() { | 4106 bool JSObject::HasDictionaryElements() { |
| 4131 return GetElementsKind() == DICTIONARY_ELEMENTS; | 4107 return GetElementsKind() == DICTIONARY_ELEMENTS; |
| 4132 } | 4108 } |
| 4133 | 4109 |
| 4134 | 4110 |
| 4111 bool JSObject::HasNonStrictArgumentsElements() { |
| 4112 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; |
| 4113 } |
| 4114 |
| 4115 |
| 4135 bool JSObject::HasExternalArrayElements() { | 4116 bool JSObject::HasExternalArrayElements() { |
| 4136 HeapObject* array = elements(); | 4117 HeapObject* array = elements(); |
| 4137 ASSERT(array != NULL); | 4118 ASSERT(array != NULL); |
| 4138 return array->IsExternalArray(); | 4119 return array->IsExternalArray(); |
| 4139 } | 4120 } |
| 4140 | 4121 |
| 4141 | 4122 |
| 4142 #define EXTERNAL_ELEMENTS_CHECK(name, type) \ | 4123 #define EXTERNAL_ELEMENTS_CHECK(name, type) \ |
| 4143 bool JSObject::HasExternal##name##Elements() { \ | 4124 bool JSObject::HasExternal##name##Elements() { \ |
| 4144 HeapObject* array = elements(); \ | 4125 HeapObject* array = elements(); \ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4176 | 4157 |
| 4177 bool JSObject::AllowsSetElementsLength() { | 4158 bool JSObject::AllowsSetElementsLength() { |
| 4178 bool result = elements()->IsFixedArray() || | 4159 bool result = elements()->IsFixedArray() || |
| 4179 elements()->IsFixedDoubleArray(); | 4160 elements()->IsFixedDoubleArray(); |
| 4180 ASSERT(result == !HasExternalArrayElements()); | 4161 ASSERT(result == !HasExternalArrayElements()); |
| 4181 return result; | 4162 return result; |
| 4182 } | 4163 } |
| 4183 | 4164 |
| 4184 | 4165 |
| 4185 MaybeObject* JSObject::EnsureWritableFastElements() { | 4166 MaybeObject* JSObject::EnsureWritableFastElements() { |
| 4186 ASSERT(HasFastElements()); | 4167 ASSERT(HasFastTypeElements()); |
| 4187 FixedArray* elems = FixedArray::cast(elements()); | 4168 FixedArray* elems = FixedArray::cast(elements()); |
| 4188 Isolate* isolate = GetIsolate(); | 4169 Isolate* isolate = GetIsolate(); |
| 4189 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 4170 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
| 4190 Object* writable_elems; | 4171 Object* writable_elems; |
| 4191 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( | 4172 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( |
| 4192 elems, isolate->heap()->fixed_array_map()); | 4173 elems, isolate->heap()->fixed_array_map()); |
| 4193 if (!maybe_writable_elems->ToObject(&writable_elems)) { | 4174 if (!maybe_writable_elems->ToObject(&writable_elems)) { |
| 4194 return maybe_writable_elems; | 4175 return maybe_writable_elems; |
| 4195 } | 4176 } |
| 4196 } | 4177 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4352 if (IsJSGlobalProxy()) { | 4333 if (IsJSGlobalProxy()) { |
| 4353 Object* proto = GetPrototype(); | 4334 Object* proto = GetPrototype(); |
| 4354 if (proto->IsNull()) return GetHeap()->undefined_value(); | 4335 if (proto->IsNull()) return GetHeap()->undefined_value(); |
| 4355 ASSERT(proto->IsJSGlobalObject()); | 4336 ASSERT(proto->IsJSGlobalObject()); |
| 4356 return proto; | 4337 return proto; |
| 4357 } | 4338 } |
| 4358 return this; | 4339 return this; |
| 4359 } | 4340 } |
| 4360 | 4341 |
| 4361 | 4342 |
| 4362 bool JSObject::HasHiddenPropertiesObject() { | 4343 MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) { |
| 4363 ASSERT(!IsJSGlobalProxy()); | 4344 return IsJSProxy() |
| 4364 return GetPropertyAttributePostInterceptor(this, | 4345 ? JSProxy::cast(this)->GetIdentityHash(flag) |
| 4365 GetHeap()->hidden_symbol(), | 4346 : JSObject::cast(this)->GetIdentityHash(flag); |
| 4366 false) != ABSENT; | |
| 4367 } | 4347 } |
| 4368 | 4348 |
| 4369 | 4349 |
| 4370 Object* JSObject::GetHiddenPropertiesObject() { | 4350 bool JSReceiver::HasElement(uint32_t index) { |
| 4371 ASSERT(!IsJSGlobalProxy()); | 4351 if (IsJSProxy()) { |
| 4372 PropertyAttributes attributes; | 4352 return JSProxy::cast(this)->HasElementWithHandler(index); |
| 4373 // You can't install a getter on a property indexed by the hidden symbol, | 4353 } |
| 4374 // so we can be sure that GetLocalPropertyPostInterceptor returns a real | 4354 return JSObject::cast(this)->HasElementWithReceiver(this, index); |
| 4375 // object. | |
| 4376 Object* result = | |
| 4377 GetLocalPropertyPostInterceptor(this, | |
| 4378 GetHeap()->hidden_symbol(), | |
| 4379 &attributes)->ToObjectUnchecked(); | |
| 4380 return result; | |
| 4381 } | |
| 4382 | |
| 4383 | |
| 4384 MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) { | |
| 4385 ASSERT(!IsJSGlobalProxy()); | |
| 4386 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | |
| 4387 hidden_obj, | |
| 4388 DONT_ENUM, | |
| 4389 kNonStrictMode); | |
| 4390 } | |
| 4391 | |
| 4392 | |
| 4393 bool JSObject::HasHiddenProperties() { | |
| 4394 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined(); | |
| 4395 } | |
| 4396 | |
| 4397 | |
| 4398 bool JSObject::HasElement(uint32_t index) { | |
| 4399 return HasElementWithReceiver(this, index); | |
| 4400 } | 4355 } |
| 4401 | 4356 |
| 4402 | 4357 |
| 4403 bool AccessorInfo::all_can_read() { | 4358 bool AccessorInfo::all_can_read() { |
| 4404 return BooleanBit::get(flag(), kAllCanReadBit); | 4359 return BooleanBit::get(flag(), kAllCanReadBit); |
| 4405 } | 4360 } |
| 4406 | 4361 |
| 4407 | 4362 |
| 4408 void AccessorInfo::set_all_can_read(bool value) { | 4363 void AccessorInfo::set_all_can_read(bool value) { |
| 4409 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value)); | 4364 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value)); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4501 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) { | 4456 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) { |
| 4502 return String::cast(other)->Hash(); | 4457 return String::cast(other)->Hash(); |
| 4503 } | 4458 } |
| 4504 | 4459 |
| 4505 | 4460 |
| 4506 MaybeObject* StringDictionaryShape::AsObject(String* key) { | 4461 MaybeObject* StringDictionaryShape::AsObject(String* key) { |
| 4507 return key; | 4462 return key; |
| 4508 } | 4463 } |
| 4509 | 4464 |
| 4510 | 4465 |
| 4511 bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) { | 4466 bool ObjectHashTableShape::IsMatch(JSReceiver* key, Object* other) { |
| 4512 return key == JSObject::cast(other); | 4467 return key == JSReceiver::cast(other); |
| 4513 } | 4468 } |
| 4514 | 4469 |
| 4515 | 4470 |
| 4516 uint32_t ObjectHashTableShape::Hash(JSObject* key) { | 4471 uint32_t ObjectHashTableShape::Hash(JSReceiver* key) { |
| 4517 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION); | 4472 MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION); |
| 4518 ASSERT(!maybe_hash->IsFailure()); | 4473 ASSERT(!maybe_hash->IsFailure()); |
| 4519 return Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 4474 return Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| 4520 } | 4475 } |
| 4521 | 4476 |
| 4522 | 4477 |
| 4523 uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) { | 4478 uint32_t ObjectHashTableShape::HashForObject(JSReceiver* key, Object* other) { |
| 4524 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash( | 4479 MaybeObject* maybe_hash = |
| 4525 JSObject::OMIT_CREATION); | 4480 JSReceiver::cast(other)->GetIdentityHash(OMIT_CREATION); |
| 4526 ASSERT(!maybe_hash->IsFailure()); | 4481 ASSERT(!maybe_hash->IsFailure()); |
| 4527 return Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 4482 return Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| 4528 } | 4483 } |
| 4529 | 4484 |
| 4530 | 4485 |
| 4531 MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) { | 4486 MaybeObject* ObjectHashTableShape::AsObject(JSReceiver* key) { |
| 4532 return key; | 4487 return key; |
| 4533 } | 4488 } |
| 4534 | 4489 |
| 4535 | 4490 |
| 4536 void ObjectHashTable::RemoveEntry(int entry) { | 4491 void ObjectHashTable::RemoveEntry(int entry) { |
| 4537 RemoveEntry(entry, GetHeap()); | 4492 RemoveEntry(entry, GetHeap()); |
| 4538 } | 4493 } |
| 4539 | 4494 |
| 4540 | 4495 |
| 4541 void Map::ClearCodeCache(Heap* heap) { | 4496 void Map::ClearCodeCache(Heap* heap) { |
| 4542 // No write barrier is needed since empty_fixed_array is not in new space. | 4497 // No write barrier is needed since empty_fixed_array is not in new space. |
| 4543 // Please note this function is used during marking: | 4498 // Please note this function is used during marking: |
| 4544 // - MarkCompactCollector::MarkUnmarkedObject | 4499 // - MarkCompactCollector::MarkUnmarkedObject |
| 4545 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); | 4500 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); |
| 4546 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); | 4501 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); |
| 4547 } | 4502 } |
| 4548 | 4503 |
| 4549 | 4504 |
| 4550 void JSArray::EnsureSize(int required_size) { | 4505 void JSArray::EnsureSize(int required_size) { |
| 4551 ASSERT(HasFastElements()); | 4506 ASSERT(HasFastTypeElements()); |
| 4552 FixedArray* elts = FixedArray::cast(elements()); | 4507 FixedArray* elts = FixedArray::cast(elements()); |
| 4553 const int kArraySizeThatFitsComfortablyInNewSpace = 128; | 4508 const int kArraySizeThatFitsComfortablyInNewSpace = 128; |
| 4554 if (elts->length() < required_size) { | 4509 if (elts->length() < required_size) { |
| 4555 // Doubling in size would be overkill, but leave some slack to avoid | 4510 // Doubling in size would be overkill, but leave some slack to avoid |
| 4556 // constantly growing. | 4511 // constantly growing. |
| 4557 Expand(required_size + (required_size >> 3)); | 4512 Expand(required_size + (required_size >> 3)); |
| 4558 // It's a performance benefit to keep a frequently used array in new-space. | 4513 // It's a performance benefit to keep a frequently used array in new-space. |
| 4559 } else if (!GetHeap()->new_space()->Contains(elts) && | 4514 } else if (!GetHeap()->new_space()->Contains(elts) && |
| 4560 required_size < kArraySizeThatFitsComfortablyInNewSpace) { | 4515 required_size < kArraySizeThatFitsComfortablyInNewSpace) { |
| 4561 // Expand will allocate a new backing store in new space even if the size | 4516 // Expand will allocate a new backing store in new space even if the size |
| 4562 // we asked for isn't larger than what we had before. | 4517 // we asked for isn't larger than what we had before. |
| 4563 Expand(required_size); | 4518 Expand(required_size); |
| 4564 } | 4519 } |
| 4565 } | 4520 } |
| 4566 | 4521 |
| 4567 | 4522 |
| 4568 void JSArray::set_length(Smi* length) { | 4523 void JSArray::set_length(Smi* length) { |
| 4524 // Don't need a write barrier for a Smi. |
| 4569 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); | 4525 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); |
| 4570 } | 4526 } |
| 4571 | 4527 |
| 4572 | 4528 |
| 4573 void JSArray::SetContent(FixedArray* storage) { | 4529 MaybeObject* JSArray::SetContent(FixedArray* storage) { |
| 4530 MaybeObject* maybe_object = EnsureCanContainElements(storage); |
| 4531 if (maybe_object->IsFailure()) return maybe_object; |
| 4574 set_length(Smi::FromInt(storage->length())); | 4532 set_length(Smi::FromInt(storage->length())); |
| 4575 set_elements(storage); | 4533 set_elements(storage); |
| 4534 return this; |
| 4576 } | 4535 } |
| 4577 | 4536 |
| 4578 | 4537 |
| 4579 MaybeObject* FixedArray::Copy() { | 4538 MaybeObject* FixedArray::Copy() { |
| 4580 if (length() == 0) return this; | 4539 if (length() == 0) return this; |
| 4581 return GetHeap()->CopyFixedArray(this); | 4540 return GetHeap()->CopyFixedArray(this); |
| 4582 } | 4541 } |
| 4583 | 4542 |
| 4584 | 4543 |
| 4585 Relocatable::Relocatable(Isolate* isolate) { | 4544 Relocatable::Relocatable(Isolate* isolate) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4682 #undef WRITE_INT_FIELD | 4641 #undef WRITE_INT_FIELD |
| 4683 #undef READ_SHORT_FIELD | 4642 #undef READ_SHORT_FIELD |
| 4684 #undef WRITE_SHORT_FIELD | 4643 #undef WRITE_SHORT_FIELD |
| 4685 #undef READ_BYTE_FIELD | 4644 #undef READ_BYTE_FIELD |
| 4686 #undef WRITE_BYTE_FIELD | 4645 #undef WRITE_BYTE_FIELD |
| 4687 | 4646 |
| 4688 | 4647 |
| 4689 } } // namespace v8::internal | 4648 } } // namespace v8::internal |
| 4690 | 4649 |
| 4691 #endif // V8_OBJECTS_INL_H_ | 4650 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |