| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 1289 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 1290 Handle<JSFunction> f = Handle<JSFunction>::cast( | 1290 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 1291 HConstant::cast(function)->handle(isolate())); | 1291 HConstant::cast(function)->handle(isolate())); |
| 1292 SharedFunctionInfo* shared = f->shared(); | 1292 SharedFunctionInfo* shared = f->shared(); |
| 1293 if (shared->strict_mode() == STRICT || shared->native()) return object; | 1293 if (shared->strict_mode() == STRICT || shared->native()) return object; |
| 1294 } | 1294 } |
| 1295 return Add<HWrapReceiver>(object, function); | 1295 return Add<HWrapReceiver>(object, function); |
| 1296 } | 1296 } |
| 1297 | 1297 |
| 1298 | 1298 |
| 1299 HValue* HGraphBuilder::BuildCheckAndGrowElementsCapacity(HValue* object, |
| 1300 HValue* elements, |
| 1301 ElementsKind kind, |
| 1302 HValue* length, |
| 1303 HValue* capacity, |
| 1304 HValue* key) { |
| 1305 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); |
| 1306 HValue* max_capacity = AddUncasted<HAdd>(capacity, max_gap); |
| 1307 Add<HBoundsCheck>(key, max_capacity); |
| 1308 |
| 1309 HValue* new_capacity = BuildNewElementsCapacity(key); |
| 1310 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| 1311 kind, kind, length, |
| 1312 new_capacity); |
| 1313 return new_elements; |
| 1314 } |
| 1315 |
| 1316 |
| 1299 HValue* HGraphBuilder::BuildCheckForCapacityGrow( | 1317 HValue* HGraphBuilder::BuildCheckForCapacityGrow( |
| 1300 HValue* object, | 1318 HValue* object, |
| 1301 HValue* elements, | 1319 HValue* elements, |
| 1302 ElementsKind kind, | 1320 ElementsKind kind, |
| 1303 HValue* length, | 1321 HValue* length, |
| 1304 HValue* key, | 1322 HValue* key, |
| 1305 bool is_js_array, | 1323 bool is_js_array, |
| 1306 PropertyAccessType access_type) { | 1324 PropertyAccessType access_type) { |
| 1307 IfBuilder length_checker(this); | 1325 IfBuilder length_checker(this); |
| 1308 | 1326 |
| 1309 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; | 1327 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; |
| 1310 length_checker.If<HCompareNumericAndBranch>(key, length, token); | 1328 length_checker.If<HCompareNumericAndBranch>(key, length, token); |
| 1311 | 1329 |
| 1312 length_checker.Then(); | 1330 length_checker.Then(); |
| 1313 | 1331 |
| 1314 HValue* current_capacity = AddLoadFixedArrayLength(elements); | 1332 HValue* current_capacity = AddLoadFixedArrayLength(elements); |
| 1315 | 1333 |
| 1316 IfBuilder capacity_checker(this); | 1334 IfBuilder capacity_checker(this); |
| 1317 | 1335 |
| 1318 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, | 1336 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, |
| 1319 Token::GTE); | 1337 Token::GTE); |
| 1320 capacity_checker.Then(); | 1338 capacity_checker.Then(); |
| 1321 | 1339 |
| 1322 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); | 1340 // BuildCheckAndGrowElementsCapacity could de-opt without profitable feedback, |
| 1323 HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap); | 1341 // therefore we defer calling it to a stub in optimized functions. It is |
| 1342 // okay to call directly in a code stub though, because a bailout to the |
| 1343 // runtime is tolerable in the corner cases. |
| 1344 if (top_info()->IsStub()) { |
| 1345 environment()->Push( |
| 1346 BuildCheckAndGrowElementsCapacity(object, elements, kind, length, |
| 1347 current_capacity, key)); |
| 1348 } else { |
| 1349 GrowArrayElementsStub stub(isolate(), is_js_array, kind); |
| 1350 CodeStubInterfaceDescriptor* descriptor = |
| 1351 isolate()->code_stub_interface_descriptor(CodeStub::GrowArrayElements); |
| 1352 HConstant* target = Add<HConstant>(stub.GetCode()); |
| 1353 HValue* op_vals[] = { context(), object, key, current_capacity }; |
| 1354 HValue* new_elements = Add<HCallWithDescriptor>( |
| 1355 target, 0, descriptor, Vector<HValue*>(op_vals, 4)); |
| 1356 // If the object changed to a dictionary, GrowArrayElements will return a |
| 1357 // smi to signal that deopt is required. |
| 1358 Add<HCheckHeapObject>(new_elements); |
| 1359 environment()->Push(new_elements); |
| 1360 } |
| 1324 | 1361 |
| 1325 Add<HBoundsCheck>(key, max_capacity); | |
| 1326 | |
| 1327 HValue* new_capacity = BuildNewElementsCapacity(key); | |
| 1328 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | |
| 1329 kind, kind, length, | |
| 1330 new_capacity); | |
| 1331 | |
| 1332 environment()->Push(new_elements); | |
| 1333 capacity_checker.Else(); | 1362 capacity_checker.Else(); |
| 1334 | 1363 |
| 1335 environment()->Push(elements); | 1364 environment()->Push(elements); |
| 1336 capacity_checker.End(); | 1365 capacity_checker.End(); |
| 1337 | 1366 |
| 1338 if (is_js_array) { | 1367 if (is_js_array) { |
| 1339 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); | 1368 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); |
| 1340 new_length->ClearFlag(HValue::kCanOverflow); | 1369 new_length->ClearFlag(HValue::kCanOverflow); |
| 1341 | 1370 |
| 1342 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), | 1371 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), |
| (...skipping 11087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12430 if (ShouldProduceTraceOutput()) { | 12459 if (ShouldProduceTraceOutput()) { |
| 12431 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12460 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12432 } | 12461 } |
| 12433 | 12462 |
| 12434 #ifdef DEBUG | 12463 #ifdef DEBUG |
| 12435 graph_->Verify(false); // No full verify. | 12464 graph_->Verify(false); // No full verify. |
| 12436 #endif | 12465 #endif |
| 12437 } | 12466 } |
| 12438 | 12467 |
| 12439 } } // namespace v8::internal | 12468 } } // namespace v8::internal |
| OLD | NEW |