OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 1290 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
1291 Handle<JSFunction> f = Handle<JSFunction>::cast( | 1291 Handle<JSFunction> f = Handle<JSFunction>::cast( |
1292 HConstant::cast(function)->handle(isolate())); | 1292 HConstant::cast(function)->handle(isolate())); |
1293 SharedFunctionInfo* shared = f->shared(); | 1293 SharedFunctionInfo* shared = f->shared(); |
1294 if (shared->strict_mode() == STRICT || shared->native()) return object; | 1294 if (shared->strict_mode() == STRICT || shared->native()) return object; |
1295 } | 1295 } |
1296 return Add<HWrapReceiver>(object, function); | 1296 return Add<HWrapReceiver>(object, function); |
1297 } | 1297 } |
1298 | 1298 |
1299 | 1299 |
1300 HValue* HGraphBuilder::BuildCheckAndGrowElementsCapacity( | |
1301 HValue* object, HValue* elements, ElementsKind kind, HValue* length, | |
1302 HValue* capacity, HValue* key) { | |
1303 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); | |
1304 HValue* max_capacity = AddUncasted<HAdd>(capacity, max_gap); | |
1305 Add<HBoundsCheck>(key, max_capacity); | |
1306 | |
1307 HValue* new_capacity = BuildNewElementsCapacity(key); | |
1308 HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, kind, | |
1309 length, new_capacity); | |
1310 return new_elements; | |
1311 } | |
1312 | |
1313 | |
1314 HValue* HGraphBuilder::BuildCheckForCapacityGrow( | 1300 HValue* HGraphBuilder::BuildCheckForCapacityGrow( |
1315 HValue* object, | 1301 HValue* object, |
1316 HValue* elements, | 1302 HValue* elements, |
1317 ElementsKind kind, | 1303 ElementsKind kind, |
1318 HValue* length, | 1304 HValue* length, |
1319 HValue* key, | 1305 HValue* key, |
1320 bool is_js_array, | 1306 bool is_js_array, |
1321 PropertyAccessType access_type) { | 1307 PropertyAccessType access_type) { |
1322 IfBuilder length_checker(this); | 1308 IfBuilder length_checker(this); |
1323 | 1309 |
1324 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; | 1310 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; |
1325 length_checker.If<HCompareNumericAndBranch>(key, length, token); | 1311 length_checker.If<HCompareNumericAndBranch>(key, length, token); |
1326 | 1312 |
1327 length_checker.Then(); | 1313 length_checker.Then(); |
1328 | 1314 |
1329 HValue* current_capacity = AddLoadFixedArrayLength(elements); | 1315 HValue* current_capacity = AddLoadFixedArrayLength(elements); |
1330 | 1316 |
1331 IfBuilder capacity_checker(this); | 1317 IfBuilder capacity_checker(this); |
1332 | 1318 |
1333 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, | 1319 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, |
1334 Token::GTE); | 1320 Token::GTE); |
1335 capacity_checker.Then(); | 1321 capacity_checker.Then(); |
1336 | 1322 |
1337 // BuildCheckAndGrowElementsCapacity could de-opt without profitable feedback, | 1323 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); |
1338 // therefore we defer calling it to a stub in optimized functions. It is | 1324 HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap); |
1339 // okay to call directly in a code stub though, because a bailout to the | |
1340 // runtime is tolerable in the corner cases. | |
1341 if (top_info()->IsStub()) { | |
1342 HValue* new_elements = BuildCheckAndGrowElementsCapacity( | |
1343 object, elements, kind, length, current_capacity, key); | |
1344 environment()->Push(new_elements); | |
1345 } else { | |
1346 GrowArrayElementsStub stub(isolate(), is_js_array, kind); | |
1347 GrowArrayElementsDescriptor descriptor(isolate()); | |
1348 HConstant* target = Add<HConstant>(stub.GetCode()); | |
1349 HValue* op_vals[] = {context(), object, key, current_capacity}; | |
1350 HValue* new_elements = Add<HCallWithDescriptor>( | |
1351 target, 0, descriptor, Vector<HValue*>(op_vals, 4)); | |
1352 // If the object changed to a dictionary, GrowArrayElements will return a | |
1353 // smi to signal that deopt is required. | |
1354 Add<HCheckHeapObject>(new_elements); | |
1355 environment()->Push(new_elements); | |
1356 } | |
1357 | 1325 |
| 1326 Add<HBoundsCheck>(key, max_capacity); |
| 1327 |
| 1328 HValue* new_capacity = BuildNewElementsCapacity(key); |
| 1329 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| 1330 kind, kind, length, |
| 1331 new_capacity); |
| 1332 |
| 1333 environment()->Push(new_elements); |
1358 capacity_checker.Else(); | 1334 capacity_checker.Else(); |
1359 | 1335 |
1360 environment()->Push(elements); | 1336 environment()->Push(elements); |
1361 capacity_checker.End(); | 1337 capacity_checker.End(); |
1362 | 1338 |
1363 if (is_js_array) { | 1339 if (is_js_array) { |
1364 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); | 1340 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); |
1365 new_length->ClearFlag(HValue::kCanOverflow); | 1341 new_length->ClearFlag(HValue::kCanOverflow); |
1366 | 1342 |
1367 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), | 1343 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), |
(...skipping 11389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12757 if (ShouldProduceTraceOutput()) { | 12733 if (ShouldProduceTraceOutput()) { |
12758 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12734 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12759 } | 12735 } |
12760 | 12736 |
12761 #ifdef DEBUG | 12737 #ifdef DEBUG |
12762 graph_->Verify(false); // No full verify. | 12738 graph_->Verify(false); // No full verify. |
12763 #endif | 12739 #endif |
12764 } | 12740 } |
12765 | 12741 |
12766 } } // namespace v8::internal | 12742 } } // namespace v8::internal |
OLD | NEW |