Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef V8_OBJECTS_H_ | 5 #ifndef V8_OBJECTS_H_ | 
| 6 #define V8_OBJECTS_H_ | 6 #define V8_OBJECTS_H_ | 
| 7 | 7 | 
| 8 #include "allocation.h" | 8 #include "allocation.h" | 
| 9 #include "assert-scope.h" | 9 #include "assert-scope.h" | 
| 10 #include "builtins.h" | 10 #include "builtins.h" | 
| (...skipping 5946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5957 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT | 5957 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT | 
| 5958 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20); | 5958 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20); | 
| 5959 class IsShared: public BitField<bool, 20, 1> {}; | 5959 class IsShared: public BitField<bool, 20, 1> {}; | 
| 5960 class DictionaryMap: public BitField<bool, 21, 1> {}; | 5960 class DictionaryMap: public BitField<bool, 21, 1> {}; | 
| 5961 class OwnsDescriptors: public BitField<bool, 22, 1> {}; | 5961 class OwnsDescriptors: public BitField<bool, 22, 1> {}; | 
| 5962 class HasInstanceCallHandler: public BitField<bool, 23, 1> {}; | 5962 class HasInstanceCallHandler: public BitField<bool, 23, 1> {}; | 
| 5963 class Deprecated: public BitField<bool, 24, 1> {}; | 5963 class Deprecated: public BitField<bool, 24, 1> {}; | 
| 5964 class IsFrozen: public BitField<bool, 25, 1> {}; | 5964 class IsFrozen: public BitField<bool, 25, 1> {}; | 
| 5965 class IsUnstable: public BitField<bool, 26, 1> {}; | 5965 class IsUnstable: public BitField<bool, 26, 1> {}; | 
| 5966 class IsMigrationTarget: public BitField<bool, 27, 1> {}; | 5966 class IsMigrationTarget: public BitField<bool, 27, 1> {}; | 
| 5967 class DoneInobjectSlackTracking: public BitField<bool, 28, 1> {}; | |
| 
 
Michael Starzinger
2014/05/21 10:42:01
nit: Alignment looks off.
 
Igor Sheludko
2014/05/22 08:05:42
Done.
 
 | |
| 5968 // Keep this bit field at the very end for better code in | |
| 5969 // Builtins::kJSConstructStubGeneric stub. | |
| 5970 class ConstructionCount: public BitField<unsigned, 29, 3> {}; | |
| 
 
Michael Starzinger
2014/05/21 10:42:01
nit: With three bits it should be fine to use plai
 
Igor Sheludko
2014/05/22 08:05:42
Done.
 
 | |
| 5967 | 5971 | 
| 5968 // Tells whether the object in the prototype property will be used | 5972 // Tells whether the object in the prototype property will be used | 
| 5969 // for instances created from this function. If the prototype | 5973 // for instances created from this function. If the prototype | 
| 5970 // property is set to a value that is not a JSObject, the prototype | 5974 // property is set to a value that is not a JSObject, the prototype | 
| 5971 // property will not be used to create instances of the function. | 5975 // property will not be used to create instances of the function. | 
| 5972 // See ECMA-262, 13.2.2. | 5976 // See ECMA-262, 13.2.2. | 
| 5973 inline void set_non_instance_prototype(bool value); | 5977 inline void set_non_instance_prototype(bool value); | 
| 5974 inline bool has_non_instance_prototype(); | 5978 inline bool has_non_instance_prototype(); | 
| 5975 | 5979 | 
| 5976 // Tells whether function has special prototype property. If not, prototype | 5980 // Tells whether function has special prototype property. If not, prototype | 
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6138 StoreMode store_mode, | 6142 StoreMode store_mode, | 
| 6139 PropertyAttributes attributes, | 6143 PropertyAttributes attributes, | 
| 6140 const char* reason); | 6144 const char* reason); | 
| 6141 | 6145 | 
| 6142 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode); | 6146 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode); | 
| 6143 | 6147 | 
| 6144 // Returns the constructor name (the name (possibly, inferred name) of the | 6148 // Returns the constructor name (the name (possibly, inferred name) of the | 
| 6145 // function that was used to instantiate the object). | 6149 // function that was used to instantiate the object). | 
| 6146 String* constructor_name(); | 6150 String* constructor_name(); | 
| 6147 | 6151 | 
| 6148 // Tells whether the map is attached to SharedFunctionInfo | |
| 6149 // (for inobject slack tracking). | |
| 6150 inline void set_attached_to_shared_function_info(bool value); | |
| 6151 | |
| 6152 inline bool attached_to_shared_function_info(); | |
| 6153 | |
| 6154 // Tells whether the map is shared between objects that may have different | 6152 // Tells whether the map is shared between objects that may have different | 
| 6155 // behavior. If true, the map should never be modified, instead a clone | 6153 // behavior. If true, the map should never be modified, instead a clone | 
| 6156 // should be created and modified. | 6154 // should be created and modified. | 
| 6157 inline void set_is_shared(bool value); | 6155 inline void set_is_shared(bool value); | 
| 6158 inline bool is_shared(); | 6156 inline bool is_shared(); | 
| 6159 | 6157 | 
| 6160 // Tells whether the map is used for JSObjects in dictionary mode (ie | 6158 // Tells whether the map is used for JSObjects in dictionary mode (ie | 
| 6161 // normalized objects, ie objects for which HasFastProperties returns false). | 6159 // normalized objects, ie objects for which HasFastProperties returns false). | 
| 6162 // A map can never be used for both dictionary mode and fast mode JSObjects. | 6160 // A map can never be used for both dictionary mode and fast mode JSObjects. | 
| 6163 // False by default and for HeapObjects that are not JSObjects. | 6161 // False by default and for HeapObjects that are not JSObjects. | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6278 inline bool owns_descriptors(); | 6276 inline bool owns_descriptors(); | 
| 6279 inline void set_owns_descriptors(bool is_shared); | 6277 inline void set_owns_descriptors(bool is_shared); | 
| 6280 inline bool has_instance_call_handler(); | 6278 inline bool has_instance_call_handler(); | 
| 6281 inline void set_has_instance_call_handler(); | 6279 inline void set_has_instance_call_handler(); | 
| 6282 inline void freeze(); | 6280 inline void freeze(); | 
| 6283 inline bool is_frozen(); | 6281 inline bool is_frozen(); | 
| 6284 inline void mark_unstable(); | 6282 inline void mark_unstable(); | 
| 6285 inline bool is_stable(); | 6283 inline bool is_stable(); | 
| 6286 inline void set_migration_target(bool value); | 6284 inline void set_migration_target(bool value); | 
| 6287 inline bool is_migration_target(); | 6285 inline bool is_migration_target(); | 
| 6286 inline void set_done_inobject_slack_tracking(bool value); | |
| 6287 inline bool done_inobject_slack_tracking(); | |
| 6288 inline void set_construction_count(unsigned value); | |
| 6289 inline unsigned construction_count(); | |
| 6288 inline void deprecate(); | 6290 inline void deprecate(); | 
| 6289 inline bool is_deprecated(); | 6291 inline bool is_deprecated(); | 
| 6290 inline bool CanBeDeprecated(); | 6292 inline bool CanBeDeprecated(); | 
| 6291 // Returns a non-deprecated version of the input. If the input was not | 6293 // Returns a non-deprecated version of the input. If the input was not | 
| 6292 // deprecated, it is directly returned. Otherwise, the non-deprecated version | 6294 // deprecated, it is directly returned. Otherwise, the non-deprecated version | 
| 6293 // is found by re-transitioning from the root of the transition tree using the | 6295 // is found by re-transitioning from the root of the transition tree using the | 
| 6294 // descriptor array of the map. Returns NULL if no updated map is found. | 6296 // descriptor array of the map. Returns NULL if no updated map is found. | 
| 6295 // This method also applies any pending migrations along the prototype chain. | 6297 // This method also applies any pending migrations along the prototype chain. | 
| 6296 static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map) | 6298 static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map) | 
| 6297 V8_WARN_UNUSED_RESULT; | 6299 V8_WARN_UNUSED_RESULT; | 
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6518 static const int kHasNamedInterceptor = 2; | 6520 static const int kHasNamedInterceptor = 2; | 
| 6519 static const int kHasIndexedInterceptor = 3; | 6521 static const int kHasIndexedInterceptor = 3; | 
| 6520 static const int kIsUndetectable = 4; | 6522 static const int kIsUndetectable = 4; | 
| 6521 static const int kIsObserved = 5; | 6523 static const int kIsObserved = 5; | 
| 6522 static const int kIsAccessCheckNeeded = 6; | 6524 static const int kIsAccessCheckNeeded = 6; | 
| 6523 class FunctionWithPrototype: public BitField<bool, 7, 1> {}; | 6525 class FunctionWithPrototype: public BitField<bool, 7, 1> {}; | 
| 6524 | 6526 | 
| 6525 // Bit positions for bit field 2 | 6527 // Bit positions for bit field 2 | 
| 6526 static const int kIsExtensible = 0; | 6528 static const int kIsExtensible = 0; | 
| 6527 static const int kStringWrapperSafeForDefaultValueOf = 1; | 6529 static const int kStringWrapperSafeForDefaultValueOf = 1; | 
| 6528 static const int kAttachedToSharedFunctionInfo = 2; | 6530 // Currently bit 2 is not used. | 
| 6529 // No bits can be used after kElementsKindFirstBit, they are all reserved for | 6531 // No bits can be used after kElementsKindFirstBit, they are all reserved for | 
| 6530 // storing ElementKind. | 6532 // storing ElementKind. | 
| 6531 static const int kElementsKindShift = 3; | 6533 static const int kElementsKindShift = 3; | 
| 6532 static const int kElementsKindBitCount = 5; | 6534 static const int kElementsKindBitCount = 5; | 
| 6533 | 6535 | 
| 6534 // Derived values from bit field 2 | 6536 // Derived values from bit field 2 | 
| 6535 static const int kElementsKindMask = (-1 << kElementsKindShift) & | 6537 static const int kElementsKindMask = (-1 << kElementsKindShift) & | 
| 6536 ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1); | 6538 ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1); | 
| 6537 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>( | 6539 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>( | 
| 6538 (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; | 6540 (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; | 
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6911 inline void set_formal_parameter_count(int value); | 6913 inline void set_formal_parameter_count(int value); | 
| 6912 | 6914 | 
| 6913 // Set the formal parameter count so the function code will be | 6915 // Set the formal parameter count so the function code will be | 
| 6914 // called without using argument adaptor frames. | 6916 // called without using argument adaptor frames. | 
| 6915 inline void DontAdaptArguments(); | 6917 inline void DontAdaptArguments(); | 
| 6916 | 6918 | 
| 6917 // [expected_nof_properties]: Expected number of properties for the function. | 6919 // [expected_nof_properties]: Expected number of properties for the function. | 
| 6918 inline int expected_nof_properties(); | 6920 inline int expected_nof_properties(); | 
| 6919 inline void set_expected_nof_properties(int value); | 6921 inline void set_expected_nof_properties(int value); | 
| 6920 | 6922 | 
| 6921 // Inobject slack tracking is the way to reclaim unused inobject space. | |
| 6922 // | |
| 6923 // The instance size is initially determined by adding some slack to | |
| 6924 // expected_nof_properties (to allow for a few extra properties added | |
| 6925 // after the constructor). There is no guarantee that the extra space | |
| 6926 // will not be wasted. | |
| 6927 // | |
| 6928 // Here is the algorithm to reclaim the unused inobject space: | |
| 6929 // - Detect the first constructor call for this SharedFunctionInfo. | |
| 6930 // When it happens enter the "in progress" state: remember the | |
| 6931 // constructor's initial_map and install a special construct stub that | |
| 6932 // counts constructor calls. | |
| 6933 // - While the tracking is in progress create objects filled with | |
| 6934 // one_pointer_filler_map instead of undefined_value. This way they can be | |
| 6935 // resized quickly and safely. | |
| 6936 // - Once enough (kGenerousAllocationCount) objects have been created | |
| 6937 // compute the 'slack' (traverse the map transition tree starting from the | |
| 6938 // initial_map and find the lowest value of unused_property_fields). | |
| 6939 // - Traverse the transition tree again and decrease the instance size | |
| 6940 // of every map. Existing objects will resize automatically (they are | |
| 6941 // filled with one_pointer_filler_map). All further allocations will | |
| 6942 // use the adjusted instance size. | |
| 6943 // - Decrease expected_nof_properties so that an allocations made from | |
| 6944 // another context will use the adjusted instance size too. | |
| 6945 // - Exit "in progress" state by clearing the reference to the initial_map | |
| 6946 // and setting the regular construct stub (generic or inline). | |
| 6947 // | |
| 6948 // The above is the main event sequence. Some special cases are possible | |
| 6949 // while the tracking is in progress: | |
| 6950 // | |
| 6951 // - GC occurs. | |
| 6952 // Check if the initial_map is referenced by any live objects (except this | |
| 6953 // SharedFunctionInfo). If it is, continue tracking as usual. | |
| 6954 // If it is not, clear the reference and reset the tracking state. The | |
| 6955 // tracking will be initiated again on the next constructor call. | |
| 6956 // | |
| 6957 // - The constructor is called from another context. | |
| 6958 // Immediately complete the tracking, perform all the necessary changes | |
| 6959 // to maps. This is necessary because there is no efficient way to track | |
| 6960 // multiple initial_maps. | |
| 6961 // Proceed to create an object in the current context (with the adjusted | |
| 6962 // size). | |
| 6963 // | |
| 6964 // - A different constructor function sharing the same SharedFunctionInfo is | |
| 6965 // called in the same context. This could be another closure in the same | |
| 6966 // context, or the first function could have been disposed. | |
| 6967 // This is handled the same way as the previous case. | |
| 6968 // | |
| 6969 // Important: inobject slack tracking is not attempted during the snapshot | |
| 6970 // creation. | |
| 6971 | |
| 6972 static const int kGenerousAllocationCount = 8; | |
| 6973 | |
| 6974 // [construction_count]: Counter for constructor calls made during | |
| 6975 // the tracking phase. | |
| 6976 inline int construction_count(); | |
| 6977 inline void set_construction_count(int value); | |
| 6978 | |
| 6979 // [feedback_vector] - accumulates ast node feedback from full-codegen and | 6923 // [feedback_vector] - accumulates ast node feedback from full-codegen and | 
| 6980 // (increasingly) from crankshafted code where sufficient feedback isn't | 6924 // (increasingly) from crankshafted code where sufficient feedback isn't | 
| 6981 // available. Currently the field is duplicated in | 6925 // available. Currently the field is duplicated in | 
| 6982 // TypeFeedbackInfo::feedback_vector, but the allocation is done here. | 6926 // TypeFeedbackInfo::feedback_vector, but the allocation is done here. | 
| 6983 DECL_ACCESSORS(feedback_vector, FixedArray) | 6927 DECL_ACCESSORS(feedback_vector, FixedArray) | 
| 6984 | 6928 | 
| 6985 // [initial_map]: initial map of the first function called as a constructor. | |
| 6986 // Saved for the duration of the tracking phase. | |
| 6987 // This is a weak link (GC resets it to undefined_value if no other live | |
| 6988 // object reference this map). | |
| 6989 DECL_ACCESSORS(initial_map, Object) | |
| 6990 | |
| 6991 // True if the initial_map is not undefined and the countdown stub is | |
| 6992 // installed. | |
| 6993 inline bool IsInobjectSlackTrackingInProgress(); | |
| 6994 | |
| 6995 // Starts the tracking. | |
| 6996 // Stores the initial map and installs the countdown stub. | |
| 6997 // IsInobjectSlackTrackingInProgress is normally true after this call, | |
| 6998 // except when tracking have not been started (e.g. the map has no unused | |
| 6999 // properties or the snapshot is being built). | |
| 7000 void StartInobjectSlackTracking(Map* map); | |
| 7001 | |
| 7002 // Completes the tracking. | |
| 7003 // IsInobjectSlackTrackingInProgress is false after this call. | |
| 7004 void CompleteInobjectSlackTracking(); | |
| 7005 | |
| 7006 // Invoked before pointers in SharedFunctionInfo are being marked. | 6929 // Invoked before pointers in SharedFunctionInfo are being marked. | 
| 7007 // Also clears the optimized code map. | 6930 // Also clears the optimized code map. | 
| 7008 inline void BeforeVisitingPointers(); | 6931 inline void BeforeVisitingPointers(); | 
| 
 
Michael Starzinger
2014/05/21 10:42:01
The only reason we needed this callback was for de
 
Igor Sheludko
2014/05/22 08:05:42
I'll do the cleanup in a next CL.
 
 | |
| 7009 | 6932 | 
| 7010 // Clears the initial_map before the GC marking phase to ensure the reference | |
| 7011 // is weak. IsInobjectSlackTrackingInProgress is false after this call. | |
| 7012 void DetachInitialMap(); | |
| 7013 | |
| 7014 // Restores the link to the initial map after the GC marking phase. | |
| 7015 // IsInobjectSlackTrackingInProgress is true after this call. | |
| 7016 void AttachInitialMap(Map* map); | |
| 7017 | |
| 7018 // False if there are definitely no live objects created from this function. | |
| 7019 // True if live objects _may_ exist (existence not guaranteed). | |
| 7020 // May go back from true to false after GC. | |
| 7021 DECL_BOOLEAN_ACCESSORS(live_objects_may_exist) | |
| 7022 | |
| 7023 // [instance class name]: class name for instances. | 6933 // [instance class name]: class name for instances. | 
| 7024 DECL_ACCESSORS(instance_class_name, Object) | 6934 DECL_ACCESSORS(instance_class_name, Object) | 
| 7025 | 6935 | 
| 7026 // [function data]: This field holds some additional data for function. | 6936 // [function data]: This field holds some additional data for function. | 
| 7027 // Currently it either has FunctionTemplateInfo to make benefit the API | 6937 // Currently it either has FunctionTemplateInfo to make benefit the API | 
| 7028 // or Smi identifying a builtin function. | 6938 // or Smi identifying a builtin function. | 
| 7029 // In the long run we don't want all functions to have this field but | 6939 // In the long run we don't want all functions to have this field but | 
| 7030 // we can fix that when we have a better model for storing hidden data | 6940 // we can fix that when we have a better model for storing hidden data | 
| 7031 // on objects. | 6941 // on objects. | 
| 7032 DECL_ACCESSORS(function_data, Object) | 6942 DECL_ACCESSORS(function_data, Object) | 
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7258 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize; | 7168 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize; | 
| 7259 static const int kInstanceClassNameOffset = | 7169 static const int kInstanceClassNameOffset = | 
| 7260 kConstructStubOffset + kPointerSize; | 7170 kConstructStubOffset + kPointerSize; | 
| 7261 static const int kFunctionDataOffset = | 7171 static const int kFunctionDataOffset = | 
| 7262 kInstanceClassNameOffset + kPointerSize; | 7172 kInstanceClassNameOffset + kPointerSize; | 
| 7263 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; | 7173 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; | 
| 7264 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; | 7174 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; | 
| 7265 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; | 7175 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; | 
| 7266 static const int kFeedbackVectorOffset = | 7176 static const int kFeedbackVectorOffset = | 
| 7267 kInferredNameOffset + kPointerSize; | 7177 kInferredNameOffset + kPointerSize; | 
| 7268 static const int kInitialMapOffset = | |
| 7269 kFeedbackVectorOffset + kPointerSize; | |
| 7270 #if V8_HOST_ARCH_32_BIT | 7178 #if V8_HOST_ARCH_32_BIT | 
| 7271 // Smi fields. | 7179 // Smi fields. | 
| 7272 static const int kLengthOffset = | 7180 static const int kLengthOffset = | 
| 7273 kInitialMapOffset + kPointerSize; | 7181 kFeedbackVectorOffset + kPointerSize; | 
| 7274 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; | 7182 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; | 
| 7275 static const int kExpectedNofPropertiesOffset = | 7183 static const int kExpectedNofPropertiesOffset = | 
| 7276 kFormalParameterCountOffset + kPointerSize; | 7184 kFormalParameterCountOffset + kPointerSize; | 
| 7277 static const int kNumLiteralsOffset = | 7185 static const int kNumLiteralsOffset = | 
| 7278 kExpectedNofPropertiesOffset + kPointerSize; | 7186 kExpectedNofPropertiesOffset + kPointerSize; | 
| 7279 static const int kStartPositionAndTypeOffset = | 7187 static const int kStartPositionAndTypeOffset = | 
| 7280 kNumLiteralsOffset + kPointerSize; | 7188 kNumLiteralsOffset + kPointerSize; | 
| 7281 static const int kEndPositionOffset = | 7189 static const int kEndPositionOffset = | 
| 7282 kStartPositionAndTypeOffset + kPointerSize; | 7190 kStartPositionAndTypeOffset + kPointerSize; | 
| 7283 static const int kFunctionTokenPositionOffset = | 7191 static const int kFunctionTokenPositionOffset = | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 7299 // The only reason to use smi fields instead of int fields | 7207 // The only reason to use smi fields instead of int fields | 
| 7300 // is to allow iteration without maps decoding during | 7208 // is to allow iteration without maps decoding during | 
| 7301 // garbage collections. | 7209 // garbage collections. | 
| 7302 // To avoid wasting space on 64-bit architectures we use | 7210 // To avoid wasting space on 64-bit architectures we use | 
| 7303 // the following trick: we group integer fields into pairs | 7211 // the following trick: we group integer fields into pairs | 
| 7304 // First integer in each pair is shifted left by 1. | 7212 // First integer in each pair is shifted left by 1. | 
| 7305 // By doing this we guarantee that LSB of each kPointerSize aligned | 7213 // By doing this we guarantee that LSB of each kPointerSize aligned | 
| 7306 // word is not set and thus this word cannot be treated as pointer | 7214 // word is not set and thus this word cannot be treated as pointer | 
| 7307 // to HeapObject during old space traversal. | 7215 // to HeapObject during old space traversal. | 
| 7308 static const int kLengthOffset = | 7216 static const int kLengthOffset = | 
| 7309 kInitialMapOffset + kPointerSize; | 7217 kFeedbackVectorOffset + kPointerSize; | 
| 7310 static const int kFormalParameterCountOffset = | 7218 static const int kFormalParameterCountOffset = | 
| 7311 kLengthOffset + kIntSize; | 7219 kLengthOffset + kIntSize; | 
| 7312 | 7220 | 
| 7313 static const int kExpectedNofPropertiesOffset = | 7221 static const int kExpectedNofPropertiesOffset = | 
| 7314 kFormalParameterCountOffset + kIntSize; | 7222 kFormalParameterCountOffset + kIntSize; | 
| 7315 static const int kNumLiteralsOffset = | 7223 static const int kNumLiteralsOffset = | 
| 7316 kExpectedNofPropertiesOffset + kIntSize; | 7224 kExpectedNofPropertiesOffset + kIntSize; | 
| 7317 | 7225 | 
| 7318 static const int kEndPositionOffset = | 7226 static const int kEndPositionOffset = | 
| 7319 kNumLiteralsOffset + kIntSize; | 7227 kNumLiteralsOffset + kIntSize; | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 7333 static const int kAstNodeCountOffset = | 7241 static const int kAstNodeCountOffset = | 
| 7334 kCountersOffset + kIntSize; | 7242 kCountersOffset + kIntSize; | 
| 7335 static const int kProfilerTicksOffset = | 7243 static const int kProfilerTicksOffset = | 
| 7336 kAstNodeCountOffset + kIntSize; | 7244 kAstNodeCountOffset + kIntSize; | 
| 7337 | 7245 | 
| 7338 // Total size. | 7246 // Total size. | 
| 7339 static const int kSize = kProfilerTicksOffset + kIntSize; | 7247 static const int kSize = kProfilerTicksOffset + kIntSize; | 
| 7340 | 7248 | 
| 7341 #endif | 7249 #endif | 
| 7342 | 7250 | 
| 7343 // The construction counter for inobject slack tracking is stored in the | |
| 7344 // most significant byte of compiler_hints which is otherwise unused. | |
| 7345 // Its offset depends on the endian-ness of the architecture. | |
| 7346 #if defined(V8_TARGET_LITTLE_ENDIAN) | |
| 7347 static const int kConstructionCountOffset = kCompilerHintsOffset + 3; | |
| 7348 #elif defined(V8_TARGET_BIG_ENDIAN) | |
| 7349 static const int kConstructionCountOffset = kCompilerHintsOffset + 0; | |
| 7350 #else | |
| 7351 #error Unknown byte ordering | |
| 7352 #endif | |
| 7353 | |
| 7354 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); | 7251 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); | 
| 7355 | 7252 | 
| 7356 typedef FixedBodyDescriptor<kNameOffset, | 7253 typedef FixedBodyDescriptor<kNameOffset, | 
| 7357 kInitialMapOffset + kPointerSize, | 7254 kFeedbackVectorOffset + kPointerSize, | 
| 7358 kSize> BodyDescriptor; | 7255 kSize> BodyDescriptor; | 
| 7359 | 7256 | 
| 7360 // Bit positions in start_position_and_type. | 7257 // Bit positions in start_position_and_type. | 
| 7361 // The source code start position is in the 30 most significant bits of | 7258 // The source code start position is in the 30 most significant bits of | 
| 7362 // the start_position_and_type field. | 7259 // the start_position_and_type field. | 
| 7363 static const int kIsExpressionBit = 0; | 7260 static const int kIsExpressionBit = 0; | 
| 7364 static const int kIsTopLevelBit = 1; | 7261 static const int kIsTopLevelBit = 1; | 
| 7365 static const int kStartPositionShift = 2; | 7262 static const int kStartPositionShift = 2; | 
| 7366 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); | 7263 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); | 
| 7367 | 7264 | 
| 7368 // Bit positions in compiler_hints. | 7265 // Bit positions in compiler_hints. | 
| 7369 enum CompilerHints { | 7266 enum CompilerHints { | 
| 7370 kAllowLazyCompilation, | 7267 kAllowLazyCompilation, | 
| 7371 kAllowLazyCompilationWithoutContext, | 7268 kAllowLazyCompilationWithoutContext, | 
| 7372 kLiveObjectsMayExist, | |
| 7373 kOptimizationDisabled, | 7269 kOptimizationDisabled, | 
| 7374 kStrictModeFunction, | 7270 kStrictModeFunction, | 
| 7375 kUsesArguments, | 7271 kUsesArguments, | 
| 7376 kHasDuplicateParameters, | 7272 kHasDuplicateParameters, | 
| 7377 kNative, | 7273 kNative, | 
| 7378 kInlineBuiltin, | 7274 kInlineBuiltin, | 
| 7379 kBoundFunction, | 7275 kBoundFunction, | 
| 7380 kIsAnonymous, | 7276 kIsAnonymous, | 
| 7381 kNameShouldPrintAsAnonymous, | 7277 kNameShouldPrintAsAnonymous, | 
| 7382 kIsFunction, | 7278 kIsFunction, | 
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7576 void MarkInOptimizationQueue(); | 7472 void MarkInOptimizationQueue(); | 
| 7577 | 7473 | 
| 7578 // Tells whether or not the function is already marked for lazy | 7474 // Tells whether or not the function is already marked for lazy | 
| 7579 // recompilation. | 7475 // recompilation. | 
| 7580 inline bool IsMarkedForOptimization(); | 7476 inline bool IsMarkedForOptimization(); | 
| 7581 inline bool IsMarkedForConcurrentOptimization(); | 7477 inline bool IsMarkedForConcurrentOptimization(); | 
| 7582 | 7478 | 
| 7583 // Tells whether or not the function is on the concurrent recompilation queue. | 7479 // Tells whether or not the function is on the concurrent recompilation queue. | 
| 7584 inline bool IsInOptimizationQueue(); | 7480 inline bool IsInOptimizationQueue(); | 
| 7585 | 7481 | 
| 7482 // Inobject slack tracking is the way to reclaim unused inobject space. | |
| 7483 // | |
| 7484 // The instance size is initially determined by adding some slack to | |
| 7485 // expected_nof_properties (to allow for a few extra properties added | |
| 7486 // after the constructor). There is no guarantee that the extra space | |
| 7487 // will not be wasted. | |
| 7488 // | |
| 7489 // Here is the algorithm to reclaim the unused inobject space: | |
| 7490 // - Detect the first constructor call for this JSFunction. | |
| 7491 // When it happens enter the "in progress" state: initialize construction | |
| 7492 // counter in the initial_map and set the |done_inobject_slack_tracking| | |
| 7493 // flag. | |
| 7494 // - While the tracking is in progress create objects filled with | |
| 7495 // one_pointer_filler_map instead of undefined_value. This way they can be | |
| 7496 // resized quickly and safely. | |
| 7497 // - Once enough (kGenerousAllocationCount) objects have been created | |
| 7498 // compute the 'slack' (traverse the map transition tree starting from the | |
| 7499 // initial_map and find the lowest value of unused_property_fields). | |
| 7500 // - Traverse the transition tree again and decrease the instance size | |
| 7501 // of every map. Existing objects will resize automatically (they are | |
| 7502 // filled with one_pointer_filler_map). All further allocations will | |
| 7503 // use the adjusted instance size. | |
| 7504 // - SharedFunctionInfo's expected_nof_properties left unmodified since | |
| 7505 // allocations made using different closures could actually create different | |
| 7506 // kind of objects (see prototype inheritance pattern). | |
| 7507 // | |
| 7508 // Important: inobject slack tracking is not attempted during the snapshot | |
| 7509 // creation. | |
| 7510 | |
| 7511 static const unsigned kGenerousAllocationCount = | |
| 
 
Michael Starzinger
2014/05/21 10:42:01
nit: Likewise, plain "int" should do it here.
 
Igor Sheludko
2014/05/22 08:05:42
Done.
 
 | |
| 7512 (1 << Map::ConstructionCount::kSize) - 1; | |
| 
 
Michael Starzinger
2014/05/21 10:42:01
nit: Just use "Map::ConstructionCount::kMax" here.
 
Igor Sheludko
2014/05/22 08:05:42
Done.
 
 | |
| 7513 static const unsigned kFinishSlackTracking = 1; | |
| 7514 static const unsigned kNoSlackTracking = 0; | |
| 7515 | |
| 7516 // True if the initial_map is set and the object constructions countdown | |
| 7517 // counter is not zero. | |
| 7518 inline bool IsInobjectSlackTrackingInProgress(); | |
| 7519 | |
| 7520 // Starts the tracking. | |
| 7521 // Initializes object constructions countdown counter in the initial map. | |
| 7522 // IsInobjectSlackTrackingInProgress is normally true after this call, | |
| 7523 // except when tracking have not been started (e.g. the map has no unused | |
| 7524 // properties or the snapshot is being built). | |
| 7525 void StartInobjectSlackTracking(); | |
| 7526 | |
| 7527 // Completes the tracking. | |
| 7528 // IsInobjectSlackTrackingInProgress is false after this call. | |
| 7529 void CompleteInobjectSlackTracking(); | |
| 7530 | |
| 7586 // [literals_or_bindings]: Fixed array holding either | 7531 // [literals_or_bindings]: Fixed array holding either | 
| 7587 // the materialized literals or the bindings of a bound function. | 7532 // the materialized literals or the bindings of a bound function. | 
| 7588 // | 7533 // | 
| 7589 // If the function contains object, regexp or array literals, the | 7534 // If the function contains object, regexp or array literals, the | 
| 7590 // literals array prefix contains the object, regexp, and array | 7535 // literals array prefix contains the object, regexp, and array | 
| 7591 // function to be used when creating these literals. This is | 7536 // function to be used when creating these literals. This is | 
| 7592 // necessary so that we do not dynamically lookup the object, regexp | 7537 // necessary so that we do not dynamically lookup the object, regexp | 
| 7593 // or array functions. Performing a dynamic lookup, we might end up | 7538 // or array functions. Performing a dynamic lookup, we might end up | 
| 7594 // using the functions from a new context that we should not have | 7539 // using the functions from a new context that we should not have | 
| 7595 // access to. | 7540 // access to. | 
| (...skipping 3521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11117 } else { | 11062 } else { | 
| 11118 value &= ~(1 << bit_position); | 11063 value &= ~(1 << bit_position); | 
| 11119 } | 11064 } | 
| 11120 return value; | 11065 return value; | 
| 11121 } | 11066 } | 
| 11122 }; | 11067 }; | 
| 11123 | 11068 | 
| 11124 } } // namespace v8::internal | 11069 } } // namespace v8::internal | 
| 11125 | 11070 | 
| 11126 #endif // V8_OBJECTS_H_ | 11071 #endif // V8_OBJECTS_H_ | 
| OLD | NEW |