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

Side by Side Diff: src/objects-inl.h

Issue 8098: - Added conditional write barrier to object accessors.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.cc ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698