| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 6093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6104 return false; | 6104 return false; |
| 6105 } | 6105 } |
| 6106 | 6106 |
| 6107 | 6107 |
| 6108 // Determines whether the given array or object literal boilerplate satisfies | 6108 // Determines whether the given array or object literal boilerplate satisfies |
| 6109 // all limits to be considered for fast deep-copying and computes the total | 6109 // all limits to be considered for fast deep-copying and computes the total |
| 6110 // size of all objects that are part of the graph. | 6110 // size of all objects that are part of the graph. |
| 6111 static bool IsFastLiteral(Handle<JSObject> boilerplate, | 6111 static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| 6112 int max_depth, | 6112 int max_depth, |
| 6113 int* max_properties, | 6113 int* max_properties, |
| 6114 int* total_size) { | 6114 int* data_size, |
| 6115 int* pointer_size) { |
| 6115 ASSERT(max_depth >= 0 && *max_properties >= 0); | 6116 ASSERT(max_depth >= 0 && *max_properties >= 0); |
| 6116 if (max_depth == 0) return false; | 6117 if (max_depth == 0) return false; |
| 6117 | 6118 |
| 6118 Isolate* isolate = boilerplate->GetIsolate(); | 6119 Isolate* isolate = boilerplate->GetIsolate(); |
| 6119 Handle<FixedArrayBase> elements(boilerplate->elements()); | 6120 Handle<FixedArrayBase> elements(boilerplate->elements()); |
| 6120 if (elements->length() > 0 && | 6121 if (elements->length() > 0 && |
| 6121 elements->map() != isolate->heap()->fixed_cow_array_map()) { | 6122 elements->map() != isolate->heap()->fixed_cow_array_map()) { |
| 6122 if (boilerplate->HasFastDoubleElements()) { | 6123 if (boilerplate->HasFastDoubleElements()) { |
| 6123 *total_size += FixedDoubleArray::SizeFor(elements->length()); | 6124 *data_size += FixedDoubleArray::SizeFor(elements->length()); |
| 6124 } else if (boilerplate->HasFastObjectElements()) { | 6125 } else if (boilerplate->HasFastObjectElements()) { |
| 6125 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 6126 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 6126 int length = elements->length(); | 6127 int length = elements->length(); |
| 6127 for (int i = 0; i < length; i++) { | 6128 for (int i = 0; i < length; i++) { |
| 6128 if ((*max_properties)-- == 0) return false; | 6129 if ((*max_properties)-- == 0) return false; |
| 6129 Handle<Object> value(fast_elements->get(i), isolate); | 6130 Handle<Object> value(fast_elements->get(i), isolate); |
| 6130 if (value->IsJSObject()) { | 6131 if (value->IsJSObject()) { |
| 6131 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 6132 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 6132 if (!IsFastLiteral(value_object, | 6133 if (!IsFastLiteral(value_object, |
| 6133 max_depth - 1, | 6134 max_depth - 1, |
| 6134 max_properties, | 6135 max_properties, |
| 6135 total_size)) { | 6136 data_size, |
| 6137 pointer_size)) { |
| 6136 return false; | 6138 return false; |
| 6137 } | 6139 } |
| 6138 } | 6140 } |
| 6139 } | 6141 } |
| 6140 *total_size += FixedArray::SizeFor(length); | 6142 *pointer_size += FixedArray::SizeFor(length); |
| 6141 } else { | 6143 } else { |
| 6142 return false; | 6144 return false; |
| 6143 } | 6145 } |
| 6144 } | 6146 } |
| 6145 | 6147 |
| 6146 Handle<FixedArray> properties(boilerplate->properties()); | 6148 Handle<FixedArray> properties(boilerplate->properties()); |
| 6147 if (properties->length() > 0) { | 6149 if (properties->length() > 0) { |
| 6148 return false; | 6150 return false; |
| 6149 } else { | 6151 } else { |
| 6150 int nof = boilerplate->map()->inobject_properties(); | 6152 int nof = boilerplate->map()->inobject_properties(); |
| 6151 for (int i = 0; i < nof; i++) { | 6153 for (int i = 0; i < nof; i++) { |
| 6152 if ((*max_properties)-- == 0) return false; | 6154 if ((*max_properties)-- == 0) return false; |
| 6153 Handle<Object> value(boilerplate->InObjectPropertyAt(i), isolate); | 6155 Handle<Object> value(boilerplate->InObjectPropertyAt(i), isolate); |
| 6154 if (value->IsJSObject()) { | 6156 if (value->IsJSObject()) { |
| 6155 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 6157 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 6156 if (!IsFastLiteral(value_object, | 6158 if (!IsFastLiteral(value_object, |
| 6157 max_depth - 1, | 6159 max_depth - 1, |
| 6158 max_properties, | 6160 max_properties, |
| 6159 total_size)) { | 6161 data_size, |
| 6162 pointer_size)) { |
| 6160 return false; | 6163 return false; |
| 6161 } | 6164 } |
| 6162 } | 6165 } |
| 6163 } | 6166 } |
| 6164 } | 6167 } |
| 6165 | 6168 |
| 6166 *total_size += boilerplate->map()->instance_size(); | 6169 *pointer_size += boilerplate->map()->instance_size(); |
| 6167 return true; | 6170 return true; |
| 6168 } | 6171 } |
| 6169 | 6172 |
| 6170 | 6173 |
| 6171 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 6174 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 6172 ASSERT(!HasStackOverflow()); | 6175 ASSERT(!HasStackOverflow()); |
| 6173 ASSERT(current_block() != NULL); | 6176 ASSERT(current_block() != NULL); |
| 6174 ASSERT(current_block()->HasPredecessor()); | 6177 ASSERT(current_block()->HasPredecessor()); |
| 6175 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 6178 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
| 6176 HValue* context = environment()->LookupContext(); | 6179 HValue* context = environment()->LookupContext(); |
| 6177 HInstruction* literal; | 6180 HInstruction* literal; |
| 6178 | 6181 |
| 6179 // Check whether to use fast or slow deep-copying for boilerplate. | 6182 // Check whether to use fast or slow deep-copying for boilerplate. |
| 6180 int total_size = 0; | 6183 int data_size = 0; |
| 6184 int pointer_size = 0; |
| 6181 int max_properties = kMaxFastLiteralProperties; | 6185 int max_properties = kMaxFastLiteralProperties; |
| 6182 Handle<Object> original_boilerplate(closure->literals()->get( | 6186 Handle<Object> original_boilerplate(closure->literals()->get( |
| 6183 expr->literal_index()), isolate()); | 6187 expr->literal_index()), isolate()); |
| 6184 if (original_boilerplate->IsJSObject() && | 6188 if (original_boilerplate->IsJSObject() && |
| 6185 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), | 6189 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), |
| 6186 kMaxFastLiteralDepth, | 6190 kMaxFastLiteralDepth, |
| 6187 &max_properties, | 6191 &max_properties, |
| 6188 &total_size)) { | 6192 &data_size, |
| 6193 &pointer_size)) { |
| 6189 Handle<JSObject> original_boilerplate_object = | 6194 Handle<JSObject> original_boilerplate_object = |
| 6190 Handle<JSObject>::cast(original_boilerplate); | 6195 Handle<JSObject>::cast(original_boilerplate); |
| 6191 Handle<JSObject> boilerplate_object = | 6196 Handle<JSObject> boilerplate_object = |
| 6192 DeepCopy(original_boilerplate_object); | 6197 DeepCopy(original_boilerplate_object); |
| 6193 | 6198 |
| 6194 literal = BuildFastLiteral(context, | 6199 literal = BuildFastLiteral(context, |
| 6195 boilerplate_object, | 6200 boilerplate_object, |
| 6196 original_boilerplate_object, | 6201 original_boilerplate_object, |
| 6197 total_size, | 6202 data_size, |
| 6203 pointer_size, |
| 6198 DONT_TRACK_ALLOCATION_SITE, | 6204 DONT_TRACK_ALLOCATION_SITE, |
| 6199 environment()->previous_ast_id()); | 6205 environment()->previous_ast_id()); |
| 6200 } else { | 6206 } else { |
| 6201 literal = AddInstruction( | 6207 literal = AddInstruction( |
| 6202 new(zone()) HObjectLiteral(context, | 6208 new(zone()) HObjectLiteral(context, |
| 6203 expr->constant_properties(), | 6209 expr->constant_properties(), |
| 6204 expr->fast_elements(), | 6210 expr->fast_elements(), |
| 6205 expr->literal_index(), | 6211 expr->literal_index(), |
| 6206 expr->depth(), | 6212 expr->depth(), |
| 6207 expr->has_function())); | 6213 expr->has_function())); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6311 ElementsKind boilerplate_elements_kind = | 6317 ElementsKind boilerplate_elements_kind = |
| 6312 Handle<JSObject>::cast(original_boilerplate_object)->GetElementsKind(); | 6318 Handle<JSObject>::cast(original_boilerplate_object)->GetElementsKind(); |
| 6313 | 6319 |
| 6314 // TODO(mvstanton): This heuristic is only a temporary solution. In the | 6320 // TODO(mvstanton): This heuristic is only a temporary solution. In the |
| 6315 // end, we want to quit creating allocation site info after a certain number | 6321 // end, we want to quit creating allocation site info after a certain number |
| 6316 // of GCs for a call site. | 6322 // of GCs for a call site. |
| 6317 AllocationSiteMode mode = AllocationSiteInfo::GetMode( | 6323 AllocationSiteMode mode = AllocationSiteInfo::GetMode( |
| 6318 boilerplate_elements_kind); | 6324 boilerplate_elements_kind); |
| 6319 | 6325 |
| 6320 // Check whether to use fast or slow deep-copying for boilerplate. | 6326 // Check whether to use fast or slow deep-copying for boilerplate. |
| 6321 int total_size = 0; | 6327 int data_size = 0; |
| 6328 int pointer_size = 0; |
| 6322 int max_properties = kMaxFastLiteralProperties; | 6329 int max_properties = kMaxFastLiteralProperties; |
| 6323 if (IsFastLiteral(original_boilerplate_object, | 6330 if (IsFastLiteral(original_boilerplate_object, |
| 6324 kMaxFastLiteralDepth, | 6331 kMaxFastLiteralDepth, |
| 6325 &max_properties, | 6332 &max_properties, |
| 6326 &total_size)) { | 6333 &data_size, |
| 6334 &pointer_size)) { |
| 6327 if (mode == TRACK_ALLOCATION_SITE) { | 6335 if (mode == TRACK_ALLOCATION_SITE) { |
| 6328 total_size += AllocationSiteInfo::kSize; | 6336 pointer_size += AllocationSiteInfo::kSize; |
| 6329 } | 6337 } |
| 6330 | 6338 |
| 6331 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); | 6339 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); |
| 6332 literal = BuildFastLiteral(context, | 6340 literal = BuildFastLiteral(context, |
| 6333 boilerplate_object, | 6341 boilerplate_object, |
| 6334 original_boilerplate_object, | 6342 original_boilerplate_object, |
| 6335 total_size, | 6343 data_size, |
| 6344 pointer_size, |
| 6336 mode, | 6345 mode, |
| 6337 environment()->previous_ast_id()); | 6346 environment()->previous_ast_id()); |
| 6338 } else { | 6347 } else { |
| 6339 literal = AddInstruction( | 6348 literal = AddInstruction( |
| 6340 new(zone()) HArrayLiteral(context, | 6349 new(zone()) HArrayLiteral(context, |
| 6341 original_boilerplate_object, | 6350 original_boilerplate_object, |
| 6342 length, | 6351 length, |
| 6343 expr->literal_index(), | 6352 expr->literal_index(), |
| 6344 expr->depth(), | 6353 expr->depth(), |
| 6345 mode)); | 6354 mode)); |
| (...skipping 3737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10083 } else { | 10092 } else { |
| 10084 return new(zone()) HThisFunction; | 10093 return new(zone()) HThisFunction; |
| 10085 } | 10094 } |
| 10086 } | 10095 } |
| 10087 | 10096 |
| 10088 | 10097 |
| 10089 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 10098 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
| 10090 HValue* context, | 10099 HValue* context, |
| 10091 Handle<JSObject> boilerplate_object, | 10100 Handle<JSObject> boilerplate_object, |
| 10092 Handle<JSObject> original_boilerplate_object, | 10101 Handle<JSObject> original_boilerplate_object, |
| 10093 int size, | 10102 int data_size, |
| 10103 int pointer_size, |
| 10094 AllocationSiteMode mode, | 10104 AllocationSiteMode mode, |
| 10095 BailoutId id) { | 10105 BailoutId id) { |
| 10096 Zone* zone = this->zone(); | 10106 Zone* zone = this->zone(); |
| 10107 int total_size = data_size + pointer_size; |
| 10097 | 10108 |
| 10098 NoObservableSideEffectsScope no_effects(this); | 10109 NoObservableSideEffectsScope no_effects(this); |
| 10099 | 10110 |
| 10100 HValue* size_in_bytes = | 10111 HValue* size_in_bytes = |
| 10101 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 10112 AddInstruction(new(zone) HConstant(total_size, |
| 10113 Representation::Integer32())); |
| 10102 HInstruction* result = | 10114 HInstruction* result = |
| 10103 AddInstruction(new(zone) HAllocate(context, | 10115 AddInstruction(new(zone) HAllocate(context, |
| 10104 size_in_bytes, | 10116 size_in_bytes, |
| 10105 HType::JSObject(), | 10117 HType::JSObject(), |
| 10106 HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); | 10118 HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
| 10107 int offset = 0; | 10119 int offset = 0; |
| 10108 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result, | 10120 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result, |
| 10109 &offset, mode, id); | 10121 &offset, mode, id); |
| 10110 ASSERT_EQ(size, offset); | 10122 ASSERT_EQ(total_size, offset); |
| 10111 return result; | 10123 return result; |
| 10112 } | 10124 } |
| 10113 | 10125 |
| 10114 | 10126 |
| 10115 void HOptimizedGraphBuilder::BuildEmitDeepCopy( | 10127 void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
| 10116 Handle<JSObject> boilerplate_object, | 10128 Handle<JSObject> boilerplate_object, |
| 10117 Handle<JSObject> original_boilerplate_object, | 10129 Handle<JSObject> original_boilerplate_object, |
| 10118 HInstruction* target, | 10130 HInstruction* target, |
| 10119 int* offset, | 10131 int* offset, |
| 10120 AllocationSiteMode mode, | 10132 AllocationSiteMode mode, |
| (...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11655 } | 11667 } |
| 11656 } | 11668 } |
| 11657 | 11669 |
| 11658 #ifdef DEBUG | 11670 #ifdef DEBUG |
| 11659 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11671 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11660 if (allocator_ != NULL) allocator_->Verify(); | 11672 if (allocator_ != NULL) allocator_->Verify(); |
| 11661 #endif | 11673 #endif |
| 11662 } | 11674 } |
| 11663 | 11675 |
| 11664 } } // namespace v8::internal | 11676 } } // namespace v8::internal |
| OLD | NEW |