OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 } | 59 } |
60 | 60 |
61 | 61 |
62 #define INT_ACCESSORS(holder, name, offset) \ | 62 #define INT_ACCESSORS(holder, name, offset) \ |
63 int holder::name() { return READ_INT_FIELD(this, offset); } \ | 63 int holder::name() { return READ_INT_FIELD(this, offset); } \ |
64 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } | 64 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } |
65 | 65 |
66 | 66 |
67 #define ACCESSORS(holder, name, type, offset) \ | 67 #define ACCESSORS(holder, name, type, offset) \ |
68 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ | 68 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ |
69 void holder::set_##name(type* value) { \ | 69 void holder::set_##name(type* value, WriteBarrierMode mode) { \ |
70 WRITE_FIELD(this, offset, value); \ | 70 WRITE_FIELD(this, offset, value); \ |
71 WRITE_BARRIER(this, offset); \ | 71 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \ |
72 } | 72 } |
73 | 73 |
74 | 74 |
| 75 |
75 #define SMI_ACCESSORS(holder, name, offset) \ | 76 #define SMI_ACCESSORS(holder, name, offset) \ |
76 int holder::name() { \ | 77 int holder::name() { \ |
77 Object* value = READ_FIELD(this, offset); \ | 78 Object* value = READ_FIELD(this, offset); \ |
78 return Smi::cast(value)->value(); \ | 79 return Smi::cast(value)->value(); \ |
79 } \ | 80 } \ |
80 void holder::set_##name(int value) { \ | 81 void holder::set_##name(int value) { \ |
81 WRITE_FIELD(this, offset, Smi::FromInt(value)); \ | 82 WRITE_FIELD(this, offset, Smi::FromInt(value)); \ |
82 } | 83 } |
83 | 84 |
84 | 85 |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 | 499 |
499 #define FIELD_ADDR(p, offset) \ | 500 #define FIELD_ADDR(p, offset) \ |
500 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) | 501 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) |
501 | 502 |
502 #define READ_FIELD(p, offset) \ | 503 #define READ_FIELD(p, offset) \ |
503 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) | 504 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) |
504 | 505 |
505 #define WRITE_FIELD(p, offset, value) \ | 506 #define WRITE_FIELD(p, offset, value) \ |
506 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) | 507 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) |
507 | 508 |
| 509 |
508 #define WRITE_BARRIER(object, offset) \ | 510 #define WRITE_BARRIER(object, offset) \ |
509 Heap::RecordWrite(object->address(), offset); | 511 Heap::RecordWrite(object->address(), offset); |
510 | 512 |
| 513 // CONITIONAL_WRITE_BARRIER must be issued after the actual |
| 514 // write due to the assert validating the written value. |
| 515 #define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \ |
| 516 if (mode == UPDATE_WRITE_BARRIER) { \ |
| 517 Heap::RecordWrite(object->address(), offset); \ |
| 518 } else { \ |
| 519 ASSERT(mode == SKIP_WRITE_BARRIER); \ |
| 520 ASSERT(Heap::InNewSpace(object) || \ |
| 521 !Heap::InNewSpace(READ_FIELD(object, offset))); \ |
| 522 } |
| 523 |
511 #define READ_DOUBLE_FIELD(p, offset) \ | 524 #define READ_DOUBLE_FIELD(p, offset) \ |
512 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) | 525 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) |
513 | 526 |
514 #define WRITE_DOUBLE_FIELD(p, offset, value) \ | 527 #define WRITE_DOUBLE_FIELD(p, offset, value) \ |
515 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) | 528 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) |
516 | 529 |
517 #define READ_INT_FIELD(p, offset) \ | 530 #define READ_INT_FIELD(p, offset) \ |
518 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset))) | 531 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset))) |
519 | 532 |
520 #define WRITE_INT_FIELD(p, offset, value) \ | 533 #define WRITE_INT_FIELD(p, offset, value) \ |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 // to adjust the index here. | 946 // to adjust the index here. |
934 int offset = GetHeaderSize() + (kPointerSize * index); | 947 int offset = GetHeaderSize() + (kPointerSize * index); |
935 WRITE_FIELD(this, offset, value); | 948 WRITE_FIELD(this, offset, value); |
936 WRITE_BARRIER(this, offset); | 949 WRITE_BARRIER(this, offset); |
937 } | 950 } |
938 | 951 |
939 | 952 |
940 // Access fast-case object properties at index. The use of these routines | 953 // Access fast-case object properties at index. The use of these routines |
941 // is needed to correctly distinguish between properties stored in-object and | 954 // is needed to correctly distinguish between properties stored in-object and |
942 // properties stored in the properties array. | 955 // properties stored in the properties array. |
943 inline Object* JSObject::FastPropertyAt(int index) { | 956 Object* JSObject::FastPropertyAt(int index) { |
944 // Adjust for the number of properties stored in the object. | 957 // Adjust for the number of properties stored in the object. |
945 index -= map()->inobject_properties(); | 958 index -= map()->inobject_properties(); |
946 if (index < 0) { | 959 if (index < 0) { |
947 int offset = map()->instance_size() + (index * kPointerSize); | 960 int offset = map()->instance_size() + (index * kPointerSize); |
948 return READ_FIELD(this, offset); | 961 return READ_FIELD(this, offset); |
949 } else { | 962 } else { |
950 ASSERT(index < properties()->length()); | 963 ASSERT(index < properties()->length()); |
951 return properties()->get(index); | 964 return properties()->get(index); |
952 } | 965 } |
953 } | 966 } |
954 | 967 |
955 | 968 |
956 inline Object* JSObject::FastPropertyAtPut(int index, Object* value) { | 969 Object* JSObject::FastPropertyAtPut(int index, Object* value) { |
957 // Adjust for the number of properties stored in the object. | 970 // Adjust for the number of properties stored in the object. |
958 index -= map()->inobject_properties(); | 971 index -= map()->inobject_properties(); |
959 if (index < 0) { | 972 if (index < 0) { |
960 int offset = map()->instance_size() + (index * kPointerSize); | 973 int offset = map()->instance_size() + (index * kPointerSize); |
961 WRITE_FIELD(this, offset, value); | 974 WRITE_FIELD(this, offset, value); |
962 WRITE_BARRIER(this, offset); | 975 WRITE_BARRIER(this, offset); |
963 } else { | 976 } else { |
964 ASSERT(index < properties()->length()); | 977 ASSERT(index < properties()->length()); |
965 properties()->set(index, value); | 978 properties()->set(index, value); |
966 } | 979 } |
967 return value; | 980 return value; |
968 } | 981 } |
969 | 982 |
970 | 983 |
| 984 Object* JSObject::InObjectPropertyAtPut(int index, |
| 985 Object* value, |
| 986 WriteBarrierMode mode) { |
| 987 // Adjust for the number of properties stored in the object. |
| 988 index -= map()->inobject_properties(); |
| 989 ASSERT(index < 0); |
| 990 int offset = map()->instance_size() + (index * kPointerSize); |
| 991 WRITE_FIELD(this, offset, value); |
| 992 CONDITIONAL_WRITE_BARRIER(this, offset, mode); |
| 993 return value; |
| 994 } |
| 995 |
| 996 |
| 997 |
971 void JSObject::InitializeBody(int object_size) { | 998 void JSObject::InitializeBody(int object_size) { |
972 Object* value = Heap::undefined_value(); | 999 Object* value = Heap::undefined_value(); |
973 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { | 1000 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { |
974 WRITE_FIELD(this, offset, value); | 1001 WRITE_FIELD(this, offset, value); |
975 } | 1002 } |
976 } | 1003 } |
977 | 1004 |
978 | 1005 |
979 void Struct::InitializeBody(int object_size) { | 1006 void Struct::InitializeBody(int object_size) { |
980 Object* value = Heap::undefined_value(); | 1007 Object* value = Heap::undefined_value(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 | 1055 |
1029 | 1056 |
1030 void FixedArray::set(int index, Object* value) { | 1057 void FixedArray::set(int index, Object* value) { |
1031 ASSERT(index >= 0 && index < this->length()); | 1058 ASSERT(index >= 0 && index < this->length()); |
1032 int offset = kHeaderSize + index * kPointerSize; | 1059 int offset = kHeaderSize + index * kPointerSize; |
1033 WRITE_FIELD(this, offset, value); | 1060 WRITE_FIELD(this, offset, value); |
1034 WRITE_BARRIER(this, offset); | 1061 WRITE_BARRIER(this, offset); |
1035 } | 1062 } |
1036 | 1063 |
1037 | 1064 |
1038 FixedArray::WriteBarrierMode FixedArray::GetWriteBarrierMode() { | 1065 WriteBarrierMode HeapObject::GetWriteBarrierMode() { |
1039 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER; | 1066 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER; |
1040 return UPDATE_WRITE_BARRIER; | 1067 return UPDATE_WRITE_BARRIER; |
1041 } | 1068 } |
1042 | 1069 |
1043 | 1070 |
1044 void FixedArray::set(int index, | 1071 void FixedArray::set(int index, |
1045 Object* value, | 1072 Object* value, |
1046 FixedArray::WriteBarrierMode mode) { | 1073 WriteBarrierMode mode) { |
1047 ASSERT(index >= 0 && index < this->length()); | 1074 ASSERT(index >= 0 && index < this->length()); |
1048 int offset = kHeaderSize + index * kPointerSize; | 1075 int offset = kHeaderSize + index * kPointerSize; |
1049 WRITE_FIELD(this, offset, value); | 1076 WRITE_FIELD(this, offset, value); |
1050 if (mode == UPDATE_WRITE_BARRIER) { | 1077 CONDITIONAL_WRITE_BARRIER(this, offset, mode); |
1051 WRITE_BARRIER(this, offset); | |
1052 } else { | |
1053 ASSERT(mode == SKIP_WRITE_BARRIER); | |
1054 ASSERT(Heap::InNewSpace(this) || !Heap::InNewSpace(value)); | |
1055 } | |
1056 } | 1078 } |
1057 | 1079 |
1058 | 1080 |
1059 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { | 1081 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { |
1060 ASSERT(index >= 0 && index < array->length()); | 1082 ASSERT(index >= 0 && index < array->length()); |
1061 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); | 1083 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); |
1062 } | 1084 } |
1063 | 1085 |
1064 | 1086 |
1065 void FixedArray::set_undefined(int index) { | 1087 void FixedArray::set_undefined(int index) { |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 int bits = flags & ~kFlagsTypeMask; | 1819 int bits = flags & ~kFlagsTypeMask; |
1798 return static_cast<Flags>(bits); | 1820 return static_cast<Flags>(bits); |
1799 } | 1821 } |
1800 | 1822 |
1801 | 1823 |
1802 Object* Map::prototype() { | 1824 Object* Map::prototype() { |
1803 return READ_FIELD(this, kPrototypeOffset); | 1825 return READ_FIELD(this, kPrototypeOffset); |
1804 } | 1826 } |
1805 | 1827 |
1806 | 1828 |
1807 void Map::set_prototype(Object* value) { | 1829 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
1808 ASSERT(value->IsNull() || value->IsJSObject()); | 1830 ASSERT(value->IsNull() || value->IsJSObject()); |
1809 WRITE_FIELD(this, kPrototypeOffset, value); | 1831 WRITE_FIELD(this, kPrototypeOffset, value); |
1810 WRITE_BARRIER(this, kPrototypeOffset); | 1832 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode); |
1811 } | 1833 } |
1812 | 1834 |
1813 | 1835 |
1814 ACCESSORS(Map, instance_descriptors, DescriptorArray, | 1836 ACCESSORS(Map, instance_descriptors, DescriptorArray, |
1815 kInstanceDescriptorsOffset) | 1837 kInstanceDescriptorsOffset) |
1816 ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset) | 1838 ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset) |
1817 ACCESSORS(Map, constructor, Object, kConstructorOffset) | 1839 ACCESSORS(Map, constructor, Object, kConstructorOffset) |
1818 | 1840 |
1819 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) | 1841 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) |
1820 ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset) | 1842 ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 set_start_position_and_type((start_position << kStartPositionShift) | 1963 set_start_position_and_type((start_position << kStartPositionShift) |
1942 | (start_position_and_type() & ~kStartPositionMask)); | 1964 | (start_position_and_type() & ~kStartPositionMask)); |
1943 } | 1965 } |
1944 | 1966 |
1945 | 1967 |
1946 Code* SharedFunctionInfo::code() { | 1968 Code* SharedFunctionInfo::code() { |
1947 return Code::cast(READ_FIELD(this, kCodeOffset)); | 1969 return Code::cast(READ_FIELD(this, kCodeOffset)); |
1948 } | 1970 } |
1949 | 1971 |
1950 | 1972 |
1951 void SharedFunctionInfo::set_code(Code* value) { | 1973 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) { |
1952 WRITE_FIELD(this, kCodeOffset, value); | 1974 WRITE_FIELD(this, kCodeOffset, value); |
1953 WRITE_BARRIER(this, kCodeOffset); | 1975 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode); |
1954 } | 1976 } |
1955 | 1977 |
1956 | 1978 |
1957 bool SharedFunctionInfo::is_compiled() { | 1979 bool SharedFunctionInfo::is_compiled() { |
1958 // TODO(1242782): Create a code kind for uncompiled code. | 1980 // TODO(1242782): Create a code kind for uncompiled code. |
1959 return code()->kind() != Code::STUB; | 1981 return code()->kind() != Code::STUB; |
1960 } | 1982 } |
1961 | 1983 |
1962 | 1984 |
1963 bool JSFunction::IsBoilerplate() { | 1985 bool JSFunction::IsBoilerplate() { |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2340 | 2362 |
2341 | 2363 |
2342 #undef CAST_ACCESSOR | 2364 #undef CAST_ACCESSOR |
2343 #undef INT_ACCESSORS | 2365 #undef INT_ACCESSORS |
2344 #undef SMI_ACCESSORS | 2366 #undef SMI_ACCESSORS |
2345 #undef ACCESSORS | 2367 #undef ACCESSORS |
2346 #undef FIELD_ADDR | 2368 #undef FIELD_ADDR |
2347 #undef READ_FIELD | 2369 #undef READ_FIELD |
2348 #undef WRITE_FIELD | 2370 #undef WRITE_FIELD |
2349 #undef WRITE_BARRIER | 2371 #undef WRITE_BARRIER |
| 2372 #undef CONDITIONAL_WRITE_BARRIER |
2350 #undef READ_MEMADDR_FIELD | 2373 #undef READ_MEMADDR_FIELD |
2351 #undef WRITE_MEMADDR_FIELD | 2374 #undef WRITE_MEMADDR_FIELD |
2352 #undef READ_DOUBLE_FIELD | 2375 #undef READ_DOUBLE_FIELD |
2353 #undef WRITE_DOUBLE_FIELD | 2376 #undef WRITE_DOUBLE_FIELD |
2354 #undef READ_INT_FIELD | 2377 #undef READ_INT_FIELD |
2355 #undef WRITE_INT_FIELD | 2378 #undef WRITE_INT_FIELD |
2356 #undef READ_SHORT_FIELD | 2379 #undef READ_SHORT_FIELD |
2357 #undef WRITE_SHORT_FIELD | 2380 #undef WRITE_SHORT_FIELD |
2358 #undef READ_BYTE_FIELD | 2381 #undef READ_BYTE_FIELD |
2359 #undef WRITE_BYTE_FIELD | 2382 #undef WRITE_BYTE_FIELD |
2360 | 2383 |
2361 | 2384 |
2362 } } // namespace v8::internal | 2385 } } // namespace v8::internal |
2363 | 2386 |
2364 #endif // V8_OBJECTS_INL_H_ | 2387 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |