Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 874323003: Externalize deoptimization reasons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: minor change Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/assembler.cc ('k') | src/deoptimizer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/field-index.h" 9 #include "src/field-index.h"
10 #include "src/hydrogen.h" 10 #include "src/hydrogen.h"
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 UNIMPLEMENTED(); 221 UNIMPLEMENTED();
222 return NULL; 222 return NULL;
223 } 223 }
224 224
225 virtual HValue* BuildCodeUninitializedStub() { 225 virtual HValue* BuildCodeUninitializedStub() {
226 // Force a deopt that falls back to the runtime. 226 // Force a deopt that falls back to the runtime.
227 HValue* undefined = graph()->GetConstantUndefined(); 227 HValue* undefined = graph()->GetConstantUndefined();
228 IfBuilder builder(this); 228 IfBuilder builder(this);
229 builder.IfNot<HCompareObjectEqAndBranch, HValue*>(undefined, undefined); 229 builder.IfNot<HCompareObjectEqAndBranch, HValue*>(undefined, undefined);
230 builder.Then(); 230 builder.Then();
231 builder.ElseDeopt("Forced deopt to runtime"); 231 builder.ElseDeopt(Deoptimizer::kForcedDeoptToRuntime);
232 return undefined; 232 return undefined;
233 } 233 }
234 234
235 Stub* casted_stub() { return static_cast<Stub*>(stub()); } 235 Stub* casted_stub() { return static_cast<Stub*>(stub()); }
236 }; 236 };
237 237
238 238
239 Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode( 239 Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(
240 ExternalReference miss) { 240 ExternalReference miss) {
241 Factory* factory = isolate()->factory(); 241 Factory* factory = isolate()->factory();
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 362
363 if_fixed.Else(); 363 if_fixed.Else();
364 Push(BuildCloneShallowArrayNonEmpty(boilerplate, 364 Push(BuildCloneShallowArrayNonEmpty(boilerplate,
365 allocation_site, 365 allocation_site,
366 alloc_site_mode, 366 alloc_site_mode,
367 FAST_DOUBLE_ELEMENTS)); 367 FAST_DOUBLE_ELEMENTS));
368 if_fixed.End(); 368 if_fixed.End();
369 if_fixed_cow.End(); 369 if_fixed_cow.End();
370 zero_capacity.End(); 370 zero_capacity.End();
371 371
372 checker.ElseDeopt("Uninitialized boilerplate literals"); 372 checker.ElseDeopt(Deoptimizer::kUninitializedBoilerplateLiterals);
373 checker.End(); 373 checker.End();
374 374
375 return environment()->Pop(); 375 return environment()->Pop();
376 } 376 }
377 377
378 378
379 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { 379 Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
380 return DoGenerateCode(this); 380 return DoGenerateCode(this);
381 } 381 }
382 382
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 Add<HLoadNamedField>(boilerplate, nullptr, access)); 429 Add<HLoadNamedField>(boilerplate, nullptr, access));
430 } 430 }
431 431
432 DCHECK(FLAG_allocation_site_pretenuring || (size == object_size)); 432 DCHECK(FLAG_allocation_site_pretenuring || (size == object_size));
433 if (FLAG_allocation_site_pretenuring) { 433 if (FLAG_allocation_site_pretenuring) {
434 BuildCreateAllocationMemento( 434 BuildCreateAllocationMemento(
435 object, Add<HConstant>(object_size), allocation_site); 435 object, Add<HConstant>(object_size), allocation_site);
436 } 436 }
437 437
438 environment()->Push(object); 438 environment()->Push(object);
439 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); 439 checker.ElseDeopt(Deoptimizer::kUninitializedBoilerplateInFastClone);
440 checker.End(); 440 checker.End();
441 441
442 return environment()->Pop(); 442 return environment()->Pop();
443 } 443 }
444 444
445 445
446 Handle<Code> FastCloneShallowObjectStub::GenerateCode() { 446 Handle<Code> FastCloneShallowObjectStub::GenerateCode() {
447 return DoGenerateCode(this); 447 return DoGenerateCode(this);
448 } 448 }
449 449
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 HValue* backing_store_length = Add<HLoadNamedField>( 662 HValue* backing_store_length = Add<HLoadNamedField>(
663 backing_store, nullptr, HObjectAccess::ForFixedArrayLength()); 663 backing_store, nullptr, HObjectAccess::ForFixedArrayLength());
664 IfBuilder in_unmapped_range(this); 664 IfBuilder in_unmapped_range(this);
665 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, 665 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length,
666 Token::LT); 666 Token::LT);
667 in_unmapped_range.Then(); 667 in_unmapped_range.Then();
668 { 668 {
669 result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, 669 result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS,
670 NEVER_RETURN_HOLE); 670 NEVER_RETURN_HOLE);
671 } 671 }
672 in_unmapped_range.ElseDeopt("Outside of range"); 672 in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange);
673 in_unmapped_range.End(); 673 in_unmapped_range.End();
674 return result; 674 return result;
675 } 675 }
676 676
677 677
678 template <> 678 template <>
679 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { 679 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() {
680 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 680 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
681 HValue* key = GetParameter(LoadDescriptor::kNameIndex); 681 HValue* key = GetParameter(LoadDescriptor::kNameIndex);
682 682
(...skipping 20 matching lines...) Expand all
703 // 703 //
704 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value 704 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value
705 // in the unmapped arguments array, as described above. Otherwise, t is a Smi 705 // in the unmapped arguments array, as described above. Otherwise, t is a Smi
706 // index into the context array given at elements[0]. Return the value at 706 // index into the context array given at elements[0]. Return the value at
707 // context[t]. 707 // context[t].
708 708
709 key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); 709 key = AddUncasted<HForceRepresentation>(key, Representation::Smi());
710 IfBuilder positive_smi(this); 710 IfBuilder positive_smi(this);
711 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), 711 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(),
712 Token::LT); 712 Token::LT);
713 positive_smi.ThenDeopt("key is negative"); 713 positive_smi.ThenDeopt(Deoptimizer::kKeyIsNegative);
714 positive_smi.End(); 714 positive_smi.End();
715 715
716 HValue* constant_two = Add<HConstant>(2); 716 HValue* constant_two = Add<HConstant>(2);
717 HValue* elements = AddLoadElements(receiver, nullptr); 717 HValue* elements = AddLoadElements(receiver, nullptr);
718 HValue* elements_length = Add<HLoadNamedField>( 718 HValue* elements_length = Add<HLoadNamedField>(
719 elements, nullptr, HObjectAccess::ForFixedArrayLength()); 719 elements, nullptr, HObjectAccess::ForFixedArrayLength());
720 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); 720 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two);
721 IfBuilder in_range(this); 721 IfBuilder in_range(this);
722 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); 722 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT);
723 in_range.Then(); 723 in_range.Then();
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 HValue* global = 1339 HValue* global =
1340 Add<HLoadNamedField>(proxy_map, nullptr, HObjectAccess::ForPrototype()); 1340 Add<HLoadNamedField>(proxy_map, nullptr, HObjectAccess::ForPrototype());
1341 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); 1341 Handle<Map> placeholder_map = isolate()->factory()->meta_map();
1342 HValue* cell = Add<HConstant>(Map::WeakCellForMap(placeholder_map)); 1342 HValue* cell = Add<HConstant>(Map::WeakCellForMap(placeholder_map));
1343 HValue* expected_map = 1343 HValue* expected_map =
1344 Add<HLoadNamedField>(cell, nullptr, HObjectAccess::ForWeakCellValue()); 1344 Add<HLoadNamedField>(cell, nullptr, HObjectAccess::ForWeakCellValue());
1345 HValue* map = 1345 HValue* map =
1346 Add<HLoadNamedField>(global, nullptr, HObjectAccess::ForMap()); 1346 Add<HLoadNamedField>(global, nullptr, HObjectAccess::ForMap());
1347 IfBuilder map_check(this); 1347 IfBuilder map_check(this);
1348 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map); 1348 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map);
1349 map_check.ThenDeopt("Unknown map"); 1349 map_check.ThenDeopt(Deoptimizer::kUnknownMap);
1350 map_check.End(); 1350 map_check.End();
1351 } 1351 }
1352 1352
1353 HValue* weak_cell = Add<HConstant>(isolate()->factory()->NewWeakCell( 1353 HValue* weak_cell = Add<HConstant>(isolate()->factory()->NewWeakCell(
1354 StoreGlobalStub::property_cell_placeholder(isolate()))); 1354 StoreGlobalStub::property_cell_placeholder(isolate())));
1355 HValue* cell = Add<HLoadNamedField>(weak_cell, nullptr, 1355 HValue* cell = Add<HLoadNamedField>(weak_cell, nullptr,
1356 HObjectAccess::ForWeakCellValue()); 1356 HObjectAccess::ForWeakCellValue());
1357 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); 1357 HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
1358 HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access); 1358 HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access);
1359 1359
1360 if (stub->is_constant()) { 1360 if (stub->is_constant()) {
1361 IfBuilder builder(this); 1361 IfBuilder builder(this);
1362 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); 1362 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
1363 builder.Then(); 1363 builder.Then();
1364 builder.ElseDeopt("Unexpected cell contents in constant global store"); 1364 builder.ElseDeopt(
1365 Deoptimizer::kUnexpectedCellContentsInConstantGlobalStore);
1365 builder.End(); 1366 builder.End();
1366 } else { 1367 } else {
1367 // Load the payload of the global parameter cell. A hole indicates that the 1368 // Load the payload of the global parameter cell. A hole indicates that the
1368 // property has been deleted and that the store must be handled by the 1369 // property has been deleted and that the store must be handled by the
1369 // runtime. 1370 // runtime.
1370 IfBuilder builder(this); 1371 IfBuilder builder(this);
1371 HValue* hole_value = graph()->GetConstantHole(); 1372 HValue* hole_value = graph()->GetConstantHole();
1372 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value); 1373 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
1373 builder.Then(); 1374 builder.Then();
1374 builder.Deopt("Unexpected cell contents in global store"); 1375 builder.Deopt(Deoptimizer::kUnexpectedCellContentsInGlobalStore);
1375 builder.Else(); 1376 builder.Else();
1376 HStoreNamedField* store = Add<HStoreNamedField>(cell, access, value); 1377 HStoreNamedField* store = Add<HStoreNamedField>(cell, access, value);
1377 store->MarkReceiverAsCell(); 1378 store->MarkReceiverAsCell();
1378 builder.End(); 1379 builder.End();
1379 } 1380 }
1380 1381
1381 return value; 1382 return value;
1382 } 1383 }
1383 1384
1384 1385
1385 Handle<Code> StoreGlobalStub::GenerateCode() { 1386 Handle<Code> StoreGlobalStub::GenerateCode() {
1386 return DoGenerateCode(this); 1387 return DoGenerateCode(this);
1387 } 1388 }
1388 1389
1389 1390
1390 template<> 1391 template<>
1391 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() { 1392 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
1392 HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex); 1393 HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex);
1393 HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex); 1394 HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex);
1394 HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex); 1395 HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex);
1395 HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex); 1396 HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex);
1396 1397
1397 if (FLAG_trace_elements_transitions) { 1398 if (FLAG_trace_elements_transitions) {
1398 // Tracing elements transitions is the job of the runtime. 1399 // Tracing elements transitions is the job of the runtime.
1399 Add<HDeoptimize>("Tracing elements transitions", Deoptimizer::EAGER); 1400 Add<HDeoptimize>(Deoptimizer::kTracingElementsTransitions,
1401 Deoptimizer::EAGER);
1400 } else { 1402 } else {
1401 info()->MarkAsSavesCallerDoubles(); 1403 info()->MarkAsSavesCallerDoubles();
1402 1404
1403 BuildTransitionElementsKind(object, map, 1405 BuildTransitionElementsKind(object, map,
1404 casted_stub()->from_kind(), 1406 casted_stub()->from_kind(),
1405 casted_stub()->to_kind(), 1407 casted_stub()->to_kind(),
1406 casted_stub()->is_jsarray()); 1408 casted_stub()->is_jsarray());
1407 1409
1408 BuildUncheckedMonomorphicElementAccess(object, key, value, 1410 BuildUncheckedMonomorphicElementAccess(object, key, value,
1409 casted_stub()->is_jsarray(), 1411 casted_stub()->is_jsarray(),
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 HValue* hash = BuildElementIndexHash(key); 1854 HValue* hash = BuildElementIndexHash(key);
1853 1855
1854 Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash)); 1856 Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
1855 } 1857 }
1856 kind_if.Else(); 1858 kind_if.Else();
1857 1859
1858 // The SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then" 1860 // The SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then"
1859 BuildElementsKindLimitCheck(&kind_if, bit_field2, 1861 BuildElementsKindLimitCheck(&kind_if, bit_field2,
1860 SLOPPY_ARGUMENTS_ELEMENTS); 1862 SLOPPY_ARGUMENTS_ELEMENTS);
1861 // Non-strict elements are not handled. 1863 // Non-strict elements are not handled.
1862 Add<HDeoptimize>("non-strict elements in KeyedLoadGenericStub", 1864 Add<HDeoptimize>(Deoptimizer::kNonStrictElementsInKeyedLoadGenericStub,
1863 Deoptimizer::EAGER); 1865 Deoptimizer::EAGER);
1864 Push(graph()->GetConstant0()); 1866 Push(graph()->GetConstant0());
1865 1867
1866 kind_if.Else(); 1868 kind_if.Else();
1867 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, 1869 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1868 EXTERNAL_INT8_ELEMENTS); 1870 EXTERNAL_INT8_ELEMENTS);
1869 1871
1870 kind_if.Else(); 1872 kind_if.Else();
1871 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, 1873 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1872 EXTERNAL_UINT8_ELEMENTS); 1874 EXTERNAL_UINT8_ELEMENTS);
(...skipping 19 matching lines...) Expand all
1892 EXTERNAL_FLOAT32_ELEMENTS); 1894 EXTERNAL_FLOAT32_ELEMENTS);
1893 1895
1894 kind_if.Else(); 1896 kind_if.Else();
1895 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, 1897 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1896 EXTERNAL_FLOAT64_ELEMENTS); 1898 EXTERNAL_FLOAT64_ELEMENTS);
1897 1899
1898 kind_if.Else(); 1900 kind_if.Else();
1899 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2, 1901 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1900 EXTERNAL_UINT8_CLAMPED_ELEMENTS); 1902 EXTERNAL_UINT8_CLAMPED_ELEMENTS);
1901 1903
1902 kind_if.ElseDeopt("ElementsKind unhandled in KeyedLoadGenericStub"); 1904 kind_if.ElseDeopt(
1905 Deoptimizer::kElementsKindUnhandledInKeyedLoadGenericStub);
1903 1906
1904 kind_if.End(); 1907 kind_if.End();
1905 } 1908 }
1906 index_name_split.Else(); 1909 index_name_split.Else();
1907 { 1910 {
1908 // Key is a unique string. 1911 // Key is a unique string.
1909 key = Pop(); 1912 key = Pop();
1910 1913
1911 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) | 1914 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
1912 (1 << Map::kHasNamedInterceptor); 1915 (1 << Map::kHasNamedInterceptor);
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 // megamorphic case is handled as part of the default stub. 2248 // megamorphic case is handled as part of the default stub.
2246 DCHECK(!FLAG_vector_ics); 2249 DCHECK(!FLAG_vector_ics);
2247 2250
2248 // Probe the stub cache. 2251 // Probe the stub cache.
2249 Add<HTailCallThroughMegamorphicCache>(receiver, name); 2252 Add<HTailCallThroughMegamorphicCache>(receiver, name);
2250 2253
2251 // We never continue. 2254 // We never continue.
2252 return graph()->GetConstant0(); 2255 return graph()->GetConstant0();
2253 } 2256 }
2254 } } // namespace v8::internal 2257 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/assembler.cc ('k') | src/deoptimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698