| 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 5983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5994 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT | 5994 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT |
| 5995 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20); | 5995 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20); |
| 5996 class IsShared: public BitField<bool, 20, 1> {}; | 5996 class IsShared: public BitField<bool, 20, 1> {}; |
| 5997 class DictionaryMap: public BitField<bool, 21, 1> {}; | 5997 class DictionaryMap: public BitField<bool, 21, 1> {}; |
| 5998 class OwnsDescriptors: public BitField<bool, 22, 1> {}; | 5998 class OwnsDescriptors: public BitField<bool, 22, 1> {}; |
| 5999 class HasInstanceCallHandler: public BitField<bool, 23, 1> {}; | 5999 class HasInstanceCallHandler: public BitField<bool, 23, 1> {}; |
| 6000 class Deprecated: public BitField<bool, 24, 1> {}; | 6000 class Deprecated: public BitField<bool, 24, 1> {}; |
| 6001 class IsFrozen: public BitField<bool, 25, 1> {}; | 6001 class IsFrozen: public BitField<bool, 25, 1> {}; |
| 6002 class IsUnstable: public BitField<bool, 26, 1> {}; | 6002 class IsUnstable: public BitField<bool, 26, 1> {}; |
| 6003 class IsMigrationTarget: public BitField<bool, 27, 1> {}; | 6003 class IsMigrationTarget: public BitField<bool, 27, 1> {}; |
| 6004 class DoneInobjectSlackTracking: public BitField<bool, 28, 1> {}; |
| 6005 // Keep this bit field at the very end for better code in |
| 6006 // Builtins::kJSConstructStubGeneric stub. |
| 6007 class ConstructionCount: public BitField<int, 29, 3> {}; |
| 6004 | 6008 |
| 6005 // Tells whether the object in the prototype property will be used | 6009 // Tells whether the object in the prototype property will be used |
| 6006 // for instances created from this function. If the prototype | 6010 // for instances created from this function. If the prototype |
| 6007 // property is set to a value that is not a JSObject, the prototype | 6011 // property is set to a value that is not a JSObject, the prototype |
| 6008 // property will not be used to create instances of the function. | 6012 // property will not be used to create instances of the function. |
| 6009 // See ECMA-262, 13.2.2. | 6013 // See ECMA-262, 13.2.2. |
| 6010 inline void set_non_instance_prototype(bool value); | 6014 inline void set_non_instance_prototype(bool value); |
| 6011 inline bool has_non_instance_prototype(); | 6015 inline bool has_non_instance_prototype(); |
| 6012 | 6016 |
| 6013 // Tells whether function has special prototype property. If not, prototype | 6017 // Tells whether function has special prototype property. If not, prototype |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6175 StoreMode store_mode, | 6179 StoreMode store_mode, |
| 6176 PropertyAttributes attributes, | 6180 PropertyAttributes attributes, |
| 6177 const char* reason); | 6181 const char* reason); |
| 6178 | 6182 |
| 6179 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode); | 6183 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode); |
| 6180 | 6184 |
| 6181 // Returns the constructor name (the name (possibly, inferred name) of the | 6185 // Returns the constructor name (the name (possibly, inferred name) of the |
| 6182 // function that was used to instantiate the object). | 6186 // function that was used to instantiate the object). |
| 6183 String* constructor_name(); | 6187 String* constructor_name(); |
| 6184 | 6188 |
| 6185 // Tells whether the map is attached to SharedFunctionInfo | |
| 6186 // (for inobject slack tracking). | |
| 6187 inline void set_attached_to_shared_function_info(bool value); | |
| 6188 | |
| 6189 inline bool attached_to_shared_function_info(); | |
| 6190 | |
| 6191 // Tells whether the map is shared between objects that may have different | 6189 // Tells whether the map is shared between objects that may have different |
| 6192 // behavior. If true, the map should never be modified, instead a clone | 6190 // behavior. If true, the map should never be modified, instead a clone |
| 6193 // should be created and modified. | 6191 // should be created and modified. |
| 6194 inline void set_is_shared(bool value); | 6192 inline void set_is_shared(bool value); |
| 6195 inline bool is_shared(); | 6193 inline bool is_shared(); |
| 6196 | 6194 |
| 6197 // Tells whether the map is used for JSObjects in dictionary mode (ie | 6195 // Tells whether the map is used for JSObjects in dictionary mode (ie |
| 6198 // normalized objects, ie objects for which HasFastProperties returns false). | 6196 // normalized objects, ie objects for which HasFastProperties returns false). |
| 6199 // A map can never be used for both dictionary mode and fast mode JSObjects. | 6197 // A map can never be used for both dictionary mode and fast mode JSObjects. |
| 6200 // False by default and for HeapObjects that are not JSObjects. | 6198 // False by default and for HeapObjects that are not JSObjects. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6315 inline bool owns_descriptors(); | 6313 inline bool owns_descriptors(); |
| 6316 inline void set_owns_descriptors(bool is_shared); | 6314 inline void set_owns_descriptors(bool is_shared); |
| 6317 inline bool has_instance_call_handler(); | 6315 inline bool has_instance_call_handler(); |
| 6318 inline void set_has_instance_call_handler(); | 6316 inline void set_has_instance_call_handler(); |
| 6319 inline void freeze(); | 6317 inline void freeze(); |
| 6320 inline bool is_frozen(); | 6318 inline bool is_frozen(); |
| 6321 inline void mark_unstable(); | 6319 inline void mark_unstable(); |
| 6322 inline bool is_stable(); | 6320 inline bool is_stable(); |
| 6323 inline void set_migration_target(bool value); | 6321 inline void set_migration_target(bool value); |
| 6324 inline bool is_migration_target(); | 6322 inline bool is_migration_target(); |
| 6323 inline void set_done_inobject_slack_tracking(bool value); |
| 6324 inline bool done_inobject_slack_tracking(); |
| 6325 inline void set_construction_count(int value); |
| 6326 inline int construction_count(); |
| 6325 inline void deprecate(); | 6327 inline void deprecate(); |
| 6326 inline bool is_deprecated(); | 6328 inline bool is_deprecated(); |
| 6327 inline bool CanBeDeprecated(); | 6329 inline bool CanBeDeprecated(); |
| 6328 // Returns a non-deprecated version of the input. If the input was not | 6330 // Returns a non-deprecated version of the input. If the input was not |
| 6329 // deprecated, it is directly returned. Otherwise, the non-deprecated version | 6331 // deprecated, it is directly returned. Otherwise, the non-deprecated version |
| 6330 // is found by re-transitioning from the root of the transition tree using the | 6332 // is found by re-transitioning from the root of the transition tree using the |
| 6331 // descriptor array of the map. Returns NULL if no updated map is found. | 6333 // descriptor array of the map. Returns NULL if no updated map is found. |
| 6332 // This method also applies any pending migrations along the prototype chain. | 6334 // This method also applies any pending migrations along the prototype chain. |
| 6333 static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map) | 6335 static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map) |
| 6334 V8_WARN_UNUSED_RESULT; | 6336 V8_WARN_UNUSED_RESULT; |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6555 static const int kHasNamedInterceptor = 2; | 6557 static const int kHasNamedInterceptor = 2; |
| 6556 static const int kHasIndexedInterceptor = 3; | 6558 static const int kHasIndexedInterceptor = 3; |
| 6557 static const int kIsUndetectable = 4; | 6559 static const int kIsUndetectable = 4; |
| 6558 static const int kIsObserved = 5; | 6560 static const int kIsObserved = 5; |
| 6559 static const int kIsAccessCheckNeeded = 6; | 6561 static const int kIsAccessCheckNeeded = 6; |
| 6560 class FunctionWithPrototype: public BitField<bool, 7, 1> {}; | 6562 class FunctionWithPrototype: public BitField<bool, 7, 1> {}; |
| 6561 | 6563 |
| 6562 // Bit positions for bit field 2 | 6564 // Bit positions for bit field 2 |
| 6563 static const int kIsExtensible = 0; | 6565 static const int kIsExtensible = 0; |
| 6564 static const int kStringWrapperSafeForDefaultValueOf = 1; | 6566 static const int kStringWrapperSafeForDefaultValueOf = 1; |
| 6565 static const int kAttachedToSharedFunctionInfo = 2; | 6567 // Currently bit 2 is not used. |
| 6566 // No bits can be used after kElementsKindFirstBit, they are all reserved for | 6568 // No bits can be used after kElementsKindFirstBit, they are all reserved for |
| 6567 // storing ElementKind. | 6569 // storing ElementKind. |
| 6568 static const int kElementsKindShift = 3; | 6570 static const int kElementsKindShift = 3; |
| 6569 static const int kElementsKindBitCount = 5; | 6571 static const int kElementsKindBitCount = 5; |
| 6570 | 6572 |
| 6571 // Derived values from bit field 2 | 6573 // Derived values from bit field 2 |
| 6572 static const int kElementsKindMask = (-1 << kElementsKindShift) & | 6574 static const int kElementsKindMask = (-1 << kElementsKindShift) & |
| 6573 ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1); | 6575 ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1); |
| 6574 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>( | 6576 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>( |
| 6575 (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; | 6577 (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6948 inline void set_formal_parameter_count(int value); | 6950 inline void set_formal_parameter_count(int value); |
| 6949 | 6951 |
| 6950 // Set the formal parameter count so the function code will be | 6952 // Set the formal parameter count so the function code will be |
| 6951 // called without using argument adaptor frames. | 6953 // called without using argument adaptor frames. |
| 6952 inline void DontAdaptArguments(); | 6954 inline void DontAdaptArguments(); |
| 6953 | 6955 |
| 6954 // [expected_nof_properties]: Expected number of properties for the function. | 6956 // [expected_nof_properties]: Expected number of properties for the function. |
| 6955 inline int expected_nof_properties(); | 6957 inline int expected_nof_properties(); |
| 6956 inline void set_expected_nof_properties(int value); | 6958 inline void set_expected_nof_properties(int value); |
| 6957 | 6959 |
| 6958 // Inobject slack tracking is the way to reclaim unused inobject space. | |
| 6959 // | |
| 6960 // The instance size is initially determined by adding some slack to | |
| 6961 // expected_nof_properties (to allow for a few extra properties added | |
| 6962 // after the constructor). There is no guarantee that the extra space | |
| 6963 // will not be wasted. | |
| 6964 // | |
| 6965 // Here is the algorithm to reclaim the unused inobject space: | |
| 6966 // - Detect the first constructor call for this SharedFunctionInfo. | |
| 6967 // When it happens enter the "in progress" state: remember the | |
| 6968 // constructor's initial_map and install a special construct stub that | |
| 6969 // counts constructor calls. | |
| 6970 // - While the tracking is in progress create objects filled with | |
| 6971 // one_pointer_filler_map instead of undefined_value. This way they can be | |
| 6972 // resized quickly and safely. | |
| 6973 // - Once enough (kGenerousAllocationCount) objects have been created | |
| 6974 // compute the 'slack' (traverse the map transition tree starting from the | |
| 6975 // initial_map and find the lowest value of unused_property_fields). | |
| 6976 // - Traverse the transition tree again and decrease the instance size | |
| 6977 // of every map. Existing objects will resize automatically (they are | |
| 6978 // filled with one_pointer_filler_map). All further allocations will | |
| 6979 // use the adjusted instance size. | |
| 6980 // - Decrease expected_nof_properties so that an allocations made from | |
| 6981 // another context will use the adjusted instance size too. | |
| 6982 // - Exit "in progress" state by clearing the reference to the initial_map | |
| 6983 // and setting the regular construct stub (generic or inline). | |
| 6984 // | |
| 6985 // The above is the main event sequence. Some special cases are possible | |
| 6986 // while the tracking is in progress: | |
| 6987 // | |
| 6988 // - GC occurs. | |
| 6989 // Check if the initial_map is referenced by any live objects (except this | |
| 6990 // SharedFunctionInfo). If it is, continue tracking as usual. | |
| 6991 // If it is not, clear the reference and reset the tracking state. The | |
| 6992 // tracking will be initiated again on the next constructor call. | |
| 6993 // | |
| 6994 // - The constructor is called from another context. | |
| 6995 // Immediately complete the tracking, perform all the necessary changes | |
| 6996 // to maps. This is necessary because there is no efficient way to track | |
| 6997 // multiple initial_maps. | |
| 6998 // Proceed to create an object in the current context (with the adjusted | |
| 6999 // size). | |
| 7000 // | |
| 7001 // - A different constructor function sharing the same SharedFunctionInfo is | |
| 7002 // called in the same context. This could be another closure in the same | |
| 7003 // context, or the first function could have been disposed. | |
| 7004 // This is handled the same way as the previous case. | |
| 7005 // | |
| 7006 // Important: inobject slack tracking is not attempted during the snapshot | |
| 7007 // creation. | |
| 7008 | |
| 7009 static const int kGenerousAllocationCount = 8; | |
| 7010 | |
| 7011 // [construction_count]: Counter for constructor calls made during | |
| 7012 // the tracking phase. | |
| 7013 inline int construction_count(); | |
| 7014 inline void set_construction_count(int value); | |
| 7015 | |
| 7016 // [feedback_vector] - accumulates ast node feedback from full-codegen and | 6960 // [feedback_vector] - accumulates ast node feedback from full-codegen and |
| 7017 // (increasingly) from crankshafted code where sufficient feedback isn't | 6961 // (increasingly) from crankshafted code where sufficient feedback isn't |
| 7018 // available. Currently the field is duplicated in | 6962 // available. Currently the field is duplicated in |
| 7019 // TypeFeedbackInfo::feedback_vector, but the allocation is done here. | 6963 // TypeFeedbackInfo::feedback_vector, but the allocation is done here. |
| 7020 DECL_ACCESSORS(feedback_vector, FixedArray) | 6964 DECL_ACCESSORS(feedback_vector, FixedArray) |
| 7021 | 6965 |
| 7022 // [initial_map]: initial map of the first function called as a constructor. | |
| 7023 // Saved for the duration of the tracking phase. | |
| 7024 // This is a weak link (GC resets it to undefined_value if no other live | |
| 7025 // object reference this map). | |
| 7026 DECL_ACCESSORS(initial_map, Object) | |
| 7027 | |
| 7028 // True if the initial_map is not undefined and the countdown stub is | |
| 7029 // installed. | |
| 7030 inline bool IsInobjectSlackTrackingInProgress(); | |
| 7031 | |
| 7032 // Starts the tracking. | |
| 7033 // Stores the initial map and installs the countdown stub. | |
| 7034 // IsInobjectSlackTrackingInProgress is normally true after this call, | |
| 7035 // except when tracking have not been started (e.g. the map has no unused | |
| 7036 // properties or the snapshot is being built). | |
| 7037 void StartInobjectSlackTracking(Map* map); | |
| 7038 | |
| 7039 // Completes the tracking. | |
| 7040 // IsInobjectSlackTrackingInProgress is false after this call. | |
| 7041 void CompleteInobjectSlackTracking(); | |
| 7042 | |
| 7043 // Invoked before pointers in SharedFunctionInfo are being marked. | 6966 // Invoked before pointers in SharedFunctionInfo are being marked. |
| 7044 // Also clears the optimized code map. | 6967 // Also clears the optimized code map. |
| 7045 inline void BeforeVisitingPointers(); | 6968 inline void BeforeVisitingPointers(); |
| 7046 | 6969 |
| 7047 // Clears the initial_map before the GC marking phase to ensure the reference | |
| 7048 // is weak. IsInobjectSlackTrackingInProgress is false after this call. | |
| 7049 void DetachInitialMap(); | |
| 7050 | |
| 7051 // Restores the link to the initial map after the GC marking phase. | |
| 7052 // IsInobjectSlackTrackingInProgress is true after this call. | |
| 7053 void AttachInitialMap(Map* map); | |
| 7054 | |
| 7055 // False if there are definitely no live objects created from this function. | |
| 7056 // True if live objects _may_ exist (existence not guaranteed). | |
| 7057 // May go back from true to false after GC. | |
| 7058 DECL_BOOLEAN_ACCESSORS(live_objects_may_exist) | |
| 7059 | |
| 7060 // [instance class name]: class name for instances. | 6970 // [instance class name]: class name for instances. |
| 7061 DECL_ACCESSORS(instance_class_name, Object) | 6971 DECL_ACCESSORS(instance_class_name, Object) |
| 7062 | 6972 |
| 7063 // [function data]: This field holds some additional data for function. | 6973 // [function data]: This field holds some additional data for function. |
| 7064 // Currently it either has FunctionTemplateInfo to make benefit the API | 6974 // Currently it either has FunctionTemplateInfo to make benefit the API |
| 7065 // or Smi identifying a builtin function. | 6975 // or Smi identifying a builtin function. |
| 7066 // In the long run we don't want all functions to have this field but | 6976 // In the long run we don't want all functions to have this field but |
| 7067 // we can fix that when we have a better model for storing hidden data | 6977 // we can fix that when we have a better model for storing hidden data |
| 7068 // on objects. | 6978 // on objects. |
| 7069 DECL_ACCESSORS(function_data, Object) | 6979 DECL_ACCESSORS(function_data, Object) |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7295 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize; | 7205 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize; |
| 7296 static const int kInstanceClassNameOffset = | 7206 static const int kInstanceClassNameOffset = |
| 7297 kConstructStubOffset + kPointerSize; | 7207 kConstructStubOffset + kPointerSize; |
| 7298 static const int kFunctionDataOffset = | 7208 static const int kFunctionDataOffset = |
| 7299 kInstanceClassNameOffset + kPointerSize; | 7209 kInstanceClassNameOffset + kPointerSize; |
| 7300 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; | 7210 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; |
| 7301 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; | 7211 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; |
| 7302 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; | 7212 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; |
| 7303 static const int kFeedbackVectorOffset = | 7213 static const int kFeedbackVectorOffset = |
| 7304 kInferredNameOffset + kPointerSize; | 7214 kInferredNameOffset + kPointerSize; |
| 7305 static const int kInitialMapOffset = | |
| 7306 kFeedbackVectorOffset + kPointerSize; | |
| 7307 #if V8_HOST_ARCH_32_BIT | 7215 #if V8_HOST_ARCH_32_BIT |
| 7308 // Smi fields. | 7216 // Smi fields. |
| 7309 static const int kLengthOffset = | 7217 static const int kLengthOffset = |
| 7310 kInitialMapOffset + kPointerSize; | 7218 kFeedbackVectorOffset + kPointerSize; |
| 7311 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; | 7219 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; |
| 7312 static const int kExpectedNofPropertiesOffset = | 7220 static const int kExpectedNofPropertiesOffset = |
| 7313 kFormalParameterCountOffset + kPointerSize; | 7221 kFormalParameterCountOffset + kPointerSize; |
| 7314 static const int kNumLiteralsOffset = | 7222 static const int kNumLiteralsOffset = |
| 7315 kExpectedNofPropertiesOffset + kPointerSize; | 7223 kExpectedNofPropertiesOffset + kPointerSize; |
| 7316 static const int kStartPositionAndTypeOffset = | 7224 static const int kStartPositionAndTypeOffset = |
| 7317 kNumLiteralsOffset + kPointerSize; | 7225 kNumLiteralsOffset + kPointerSize; |
| 7318 static const int kEndPositionOffset = | 7226 static const int kEndPositionOffset = |
| 7319 kStartPositionAndTypeOffset + kPointerSize; | 7227 kStartPositionAndTypeOffset + kPointerSize; |
| 7320 static const int kFunctionTokenPositionOffset = | 7228 static const int kFunctionTokenPositionOffset = |
| (...skipping 15 matching lines...) Expand all Loading... |
| 7336 // The only reason to use smi fields instead of int fields | 7244 // The only reason to use smi fields instead of int fields |
| 7337 // is to allow iteration without maps decoding during | 7245 // is to allow iteration without maps decoding during |
| 7338 // garbage collections. | 7246 // garbage collections. |
| 7339 // To avoid wasting space on 64-bit architectures we use | 7247 // To avoid wasting space on 64-bit architectures we use |
| 7340 // the following trick: we group integer fields into pairs | 7248 // the following trick: we group integer fields into pairs |
| 7341 // First integer in each pair is shifted left by 1. | 7249 // First integer in each pair is shifted left by 1. |
| 7342 // By doing this we guarantee that LSB of each kPointerSize aligned | 7250 // By doing this we guarantee that LSB of each kPointerSize aligned |
| 7343 // word is not set and thus this word cannot be treated as pointer | 7251 // word is not set and thus this word cannot be treated as pointer |
| 7344 // to HeapObject during old space traversal. | 7252 // to HeapObject during old space traversal. |
| 7345 static const int kLengthOffset = | 7253 static const int kLengthOffset = |
| 7346 kInitialMapOffset + kPointerSize; | 7254 kFeedbackVectorOffset + kPointerSize; |
| 7347 static const int kFormalParameterCountOffset = | 7255 static const int kFormalParameterCountOffset = |
| 7348 kLengthOffset + kIntSize; | 7256 kLengthOffset + kIntSize; |
| 7349 | 7257 |
| 7350 static const int kExpectedNofPropertiesOffset = | 7258 static const int kExpectedNofPropertiesOffset = |
| 7351 kFormalParameterCountOffset + kIntSize; | 7259 kFormalParameterCountOffset + kIntSize; |
| 7352 static const int kNumLiteralsOffset = | 7260 static const int kNumLiteralsOffset = |
| 7353 kExpectedNofPropertiesOffset + kIntSize; | 7261 kExpectedNofPropertiesOffset + kIntSize; |
| 7354 | 7262 |
| 7355 static const int kEndPositionOffset = | 7263 static const int kEndPositionOffset = |
| 7356 kNumLiteralsOffset + kIntSize; | 7264 kNumLiteralsOffset + kIntSize; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7370 static const int kAstNodeCountOffset = | 7278 static const int kAstNodeCountOffset = |
| 7371 kCountersOffset + kIntSize; | 7279 kCountersOffset + kIntSize; |
| 7372 static const int kProfilerTicksOffset = | 7280 static const int kProfilerTicksOffset = |
| 7373 kAstNodeCountOffset + kIntSize; | 7281 kAstNodeCountOffset + kIntSize; |
| 7374 | 7282 |
| 7375 // Total size. | 7283 // Total size. |
| 7376 static const int kSize = kProfilerTicksOffset + kIntSize; | 7284 static const int kSize = kProfilerTicksOffset + kIntSize; |
| 7377 | 7285 |
| 7378 #endif | 7286 #endif |
| 7379 | 7287 |
| 7380 // The construction counter for inobject slack tracking is stored in the | |
| 7381 // most significant byte of compiler_hints which is otherwise unused. | |
| 7382 // Its offset depends on the endian-ness of the architecture. | |
| 7383 #if defined(V8_TARGET_LITTLE_ENDIAN) | |
| 7384 static const int kConstructionCountOffset = kCompilerHintsOffset + 3; | |
| 7385 #elif defined(V8_TARGET_BIG_ENDIAN) | |
| 7386 static const int kConstructionCountOffset = kCompilerHintsOffset + 0; | |
| 7387 #else | |
| 7388 #error Unknown byte ordering | |
| 7389 #endif | |
| 7390 | |
| 7391 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); | 7288 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); |
| 7392 | 7289 |
| 7393 typedef FixedBodyDescriptor<kNameOffset, | 7290 typedef FixedBodyDescriptor<kNameOffset, |
| 7394 kInitialMapOffset + kPointerSize, | 7291 kFeedbackVectorOffset + kPointerSize, |
| 7395 kSize> BodyDescriptor; | 7292 kSize> BodyDescriptor; |
| 7396 | 7293 |
| 7397 // Bit positions in start_position_and_type. | 7294 // Bit positions in start_position_and_type. |
| 7398 // The source code start position is in the 30 most significant bits of | 7295 // The source code start position is in the 30 most significant bits of |
| 7399 // the start_position_and_type field. | 7296 // the start_position_and_type field. |
| 7400 static const int kIsExpressionBit = 0; | 7297 static const int kIsExpressionBit = 0; |
| 7401 static const int kIsTopLevelBit = 1; | 7298 static const int kIsTopLevelBit = 1; |
| 7402 static const int kStartPositionShift = 2; | 7299 static const int kStartPositionShift = 2; |
| 7403 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); | 7300 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); |
| 7404 | 7301 |
| 7405 // Bit positions in compiler_hints. | 7302 // Bit positions in compiler_hints. |
| 7406 enum CompilerHints { | 7303 enum CompilerHints { |
| 7407 kAllowLazyCompilation, | 7304 kAllowLazyCompilation, |
| 7408 kAllowLazyCompilationWithoutContext, | 7305 kAllowLazyCompilationWithoutContext, |
| 7409 kLiveObjectsMayExist, | |
| 7410 kOptimizationDisabled, | 7306 kOptimizationDisabled, |
| 7411 kStrictModeFunction, | 7307 kStrictModeFunction, |
| 7412 kUsesArguments, | 7308 kUsesArguments, |
| 7413 kHasDuplicateParameters, | 7309 kHasDuplicateParameters, |
| 7414 kNative, | 7310 kNative, |
| 7415 kInlineBuiltin, | 7311 kInlineBuiltin, |
| 7416 kBoundFunction, | 7312 kBoundFunction, |
| 7417 kIsAnonymous, | 7313 kIsAnonymous, |
| 7418 kNameShouldPrintAsAnonymous, | 7314 kNameShouldPrintAsAnonymous, |
| 7419 kIsFunction, | 7315 kIsFunction, |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7615 void MarkInOptimizationQueue(); | 7511 void MarkInOptimizationQueue(); |
| 7616 | 7512 |
| 7617 // Tells whether or not the function is already marked for lazy | 7513 // Tells whether or not the function is already marked for lazy |
| 7618 // recompilation. | 7514 // recompilation. |
| 7619 inline bool IsMarkedForOptimization(); | 7515 inline bool IsMarkedForOptimization(); |
| 7620 inline bool IsMarkedForConcurrentOptimization(); | 7516 inline bool IsMarkedForConcurrentOptimization(); |
| 7621 | 7517 |
| 7622 // Tells whether or not the function is on the concurrent recompilation queue. | 7518 // Tells whether or not the function is on the concurrent recompilation queue. |
| 7623 inline bool IsInOptimizationQueue(); | 7519 inline bool IsInOptimizationQueue(); |
| 7624 | 7520 |
| 7521 // Inobject slack tracking is the way to reclaim unused inobject space. |
| 7522 // |
| 7523 // The instance size is initially determined by adding some slack to |
| 7524 // expected_nof_properties (to allow for a few extra properties added |
| 7525 // after the constructor). There is no guarantee that the extra space |
| 7526 // will not be wasted. |
| 7527 // |
| 7528 // Here is the algorithm to reclaim the unused inobject space: |
| 7529 // - Detect the first constructor call for this JSFunction. |
| 7530 // When it happens enter the "in progress" state: initialize construction |
| 7531 // counter in the initial_map and set the |done_inobject_slack_tracking| |
| 7532 // flag. |
| 7533 // - While the tracking is in progress create objects filled with |
| 7534 // one_pointer_filler_map instead of undefined_value. This way they can be |
| 7535 // resized quickly and safely. |
| 7536 // - Once enough (kGenerousAllocationCount) objects have been created |
| 7537 // compute the 'slack' (traverse the map transition tree starting from the |
| 7538 // initial_map and find the lowest value of unused_property_fields). |
| 7539 // - Traverse the transition tree again and decrease the instance size |
| 7540 // of every map. Existing objects will resize automatically (they are |
| 7541 // filled with one_pointer_filler_map). All further allocations will |
| 7542 // use the adjusted instance size. |
| 7543 // - SharedFunctionInfo's expected_nof_properties left unmodified since |
| 7544 // allocations made using different closures could actually create different |
| 7545 // kind of objects (see prototype inheritance pattern). |
| 7546 // |
| 7547 // Important: inobject slack tracking is not attempted during the snapshot |
| 7548 // creation. |
| 7549 |
| 7550 static const int kGenerousAllocationCount = Map::ConstructionCount::kMax; |
| 7551 static const int kFinishSlackTracking = 1; |
| 7552 static const int kNoSlackTracking = 0; |
| 7553 |
| 7554 // True if the initial_map is set and the object constructions countdown |
| 7555 // counter is not zero. |
| 7556 inline bool IsInobjectSlackTrackingInProgress(); |
| 7557 |
| 7558 // Starts the tracking. |
| 7559 // Initializes object constructions countdown counter in the initial map. |
| 7560 // IsInobjectSlackTrackingInProgress is normally true after this call, |
| 7561 // except when tracking have not been started (e.g. the map has no unused |
| 7562 // properties or the snapshot is being built). |
| 7563 void StartInobjectSlackTracking(); |
| 7564 |
| 7565 // Completes the tracking. |
| 7566 // IsInobjectSlackTrackingInProgress is false after this call. |
| 7567 void CompleteInobjectSlackTracking(); |
| 7568 |
| 7625 // [literals_or_bindings]: Fixed array holding either | 7569 // [literals_or_bindings]: Fixed array holding either |
| 7626 // the materialized literals or the bindings of a bound function. | 7570 // the materialized literals or the bindings of a bound function. |
| 7627 // | 7571 // |
| 7628 // If the function contains object, regexp or array literals, the | 7572 // If the function contains object, regexp or array literals, the |
| 7629 // literals array prefix contains the object, regexp, and array | 7573 // literals array prefix contains the object, regexp, and array |
| 7630 // function to be used when creating these literals. This is | 7574 // function to be used when creating these literals. This is |
| 7631 // necessary so that we do not dynamically lookup the object, regexp | 7575 // necessary so that we do not dynamically lookup the object, regexp |
| 7632 // or array functions. Performing a dynamic lookup, we might end up | 7576 // or array functions. Performing a dynamic lookup, we might end up |
| 7633 // using the functions from a new context that we should not have | 7577 // using the functions from a new context that we should not have |
| 7634 // access to. | 7578 // access to. |
| (...skipping 3487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11122 } else { | 11066 } else { |
| 11123 value &= ~(1 << bit_position); | 11067 value &= ~(1 << bit_position); |
| 11124 } | 11068 } |
| 11125 return value; | 11069 return value; |
| 11126 } | 11070 } |
| 11127 }; | 11071 }; |
| 11128 | 11072 |
| 11129 } } // namespace v8::internal | 11073 } } // namespace v8::internal |
| 11130 | 11074 |
| 11131 #endif // V8_OBJECTS_H_ | 11075 #endif // V8_OBJECTS_H_ |
| OLD | NEW |