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

Side by Side Diff: src/hydrogen.cc

Issue 18050004: Add templatized convienience functions for adding hydrogen instructions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | 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 // 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 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 982
983 983
984 void HGraphBuilder::AddSimulate(BailoutId id, 984 void HGraphBuilder::AddSimulate(BailoutId id,
985 RemovableSimulate removable) { 985 RemovableSimulate removable) {
986 ASSERT(current_block() != NULL); 986 ASSERT(current_block() != NULL);
987 ASSERT(no_side_effects_scope_count_ == 0); 987 ASSERT(no_side_effects_scope_count_ == 0);
988 current_block()->AddSimulate(id, removable); 988 current_block()->AddSimulate(id, removable);
989 } 989 }
990 990
991 991
992 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) {
993 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length);
994 AddInstruction(result);
995 return result;
996 }
997
998
999 HReturn* HGraphBuilder::AddReturn(HValue* value) { 992 HReturn* HGraphBuilder::AddReturn(HValue* value) {
1000 HValue* context = environment()->LookupContext(); 993 HValue* context = environment()->LookupContext();
1001 int num_parameters = graph()->info()->num_parameters(); 994 int num_parameters = graph()->info()->num_parameters();
1002 HValue* params = AddInstruction(new(graph()->zone()) 995 HValue* params = AddInstruction(new(graph()->zone())
1003 HConstant(num_parameters)); 996 HConstant(num_parameters));
1004 HReturn* return_instruction = new(graph()->zone()) 997 HReturn* return_instruction = new(graph()->zone())
1005 HReturn(value, context, params); 998 HReturn(value, context, params);
1006 current_block()->FinishExit(return_instruction); 999 current_block()->FinishExit(return_instruction);
1007 return return_instruction; 1000 return return_instruction;
1008 } 1001 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 new_length->ClearFlag(HValue::kCanOverflow); 1161 new_length->ClearFlag(HValue::kCanOverflow);
1169 1162
1170 Representation representation = IsFastElementsKind(kind) 1163 Representation representation = IsFastElementsKind(kind)
1171 ? Representation::Smi() : Representation::Tagged(); 1164 ? Representation::Smi() : Representation::Tagged();
1172 AddStore(object, HObjectAccess::ForArrayLength(), new_length, 1165 AddStore(object, HObjectAccess::ForArrayLength(), new_length,
1173 representation); 1166 representation);
1174 } 1167 }
1175 1168
1176 length_checker.Else(); 1169 length_checker.Else();
1177 1170
1178 AddBoundsCheck(key, length); 1171 Add<HBoundsCheck>(key, length);
1179 environment()->Push(elements); 1172 environment()->Push(elements);
1180 1173
1181 length_checker.End(); 1174 length_checker.End();
1182 1175
1183 return environment()->Pop(); 1176 return environment()->Pop();
1184 } 1177 }
1185 1178
1186 1179
1187 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, 1180 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object,
1188 HValue* elements, 1181 HValue* elements,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 negative_checker.Then(); 1266 negative_checker.Then();
1274 HInstruction* result = BuildExternalArrayElementAccess( 1267 HInstruction* result = BuildExternalArrayElementAccess(
1275 external_elements, key, val, bounds_check, 1268 external_elements, key, val, bounds_check,
1276 elements_kind, is_store); 1269 elements_kind, is_store);
1277 AddInstruction(result); 1270 AddInstruction(result);
1278 negative_checker.ElseDeopt(); 1271 negative_checker.ElseDeopt();
1279 length_checker.End(); 1272 length_checker.End();
1280 return result; 1273 return result;
1281 } else { 1274 } else {
1282 ASSERT(store_mode == STANDARD_STORE); 1275 ASSERT(store_mode == STANDARD_STORE);
1283 checked_key = AddBoundsCheck(key, length); 1276 checked_key = Add<HBoundsCheck>(key, length);
1284 HLoadExternalArrayPointer* external_elements = 1277 HLoadExternalArrayPointer* external_elements =
1285 new(zone) HLoadExternalArrayPointer(elements); 1278 new(zone) HLoadExternalArrayPointer(elements);
1286 AddInstruction(external_elements); 1279 AddInstruction(external_elements);
1287 return AddInstruction(BuildExternalArrayElementAccess( 1280 return AddInstruction(BuildExternalArrayElementAccess(
1288 external_elements, checked_key, val, mapcheck, 1281 external_elements, checked_key, val, mapcheck,
1289 elements_kind, is_store)); 1282 elements_kind, is_store));
1290 } 1283 }
1291 } 1284 }
1292 ASSERT(fast_smi_only_elements || 1285 ASSERT(fast_smi_only_elements ||
1293 fast_elements || 1286 fast_elements ||
1294 IsFastDoubleElementsKind(elements_kind)); 1287 IsFastDoubleElementsKind(elements_kind));
1295 1288
1296 // In case val is stored into a fast smi array, assure that the value is a smi 1289 // In case val is stored into a fast smi array, assure that the value is a smi
1297 // before manipulating the backing store. Otherwise the actual store may 1290 // before manipulating the backing store. Otherwise the actual store may
1298 // deopt, leaving the backing store in an invalid state. 1291 // deopt, leaving the backing store in an invalid state.
1299 if (is_store && IsFastSmiElementsKind(elements_kind) && 1292 if (is_store && IsFastSmiElementsKind(elements_kind) &&
1300 !val->type().IsSmi()) { 1293 !val->type().IsSmi()) {
1301 val = AddInstruction(new(zone) HForceRepresentation( 1294 val = AddInstruction(new(zone) HForceRepresentation(
1302 val, Representation::Smi())); 1295 val, Representation::Smi()));
1303 } 1296 }
1304 1297
1305 if (IsGrowStoreMode(store_mode)) { 1298 if (IsGrowStoreMode(store_mode)) {
1306 NoObservableSideEffectsScope no_effects(this); 1299 NoObservableSideEffectsScope no_effects(this);
1307 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, 1300 elements = BuildCheckForCapacityGrow(object, elements, elements_kind,
1308 length, key, is_js_array); 1301 length, key, is_js_array);
1309 checked_key = key; 1302 checked_key = key;
1310 } else { 1303 } else {
1311 checked_key = AddBoundsCheck(key, length); 1304 checked_key = Add<HBoundsCheck>(key, length);
1312 1305
1313 if (is_store && (fast_elements || fast_smi_only_elements)) { 1306 if (is_store && (fast_elements || fast_smi_only_elements)) {
1314 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 1307 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
1315 NoObservableSideEffectsScope no_effects(this); 1308 NoObservableSideEffectsScope no_effects(this);
1316 1309
1317 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, 1310 elements = BuildCopyElementsOnWrite(object, elements, elements_kind,
1318 length); 1311 length);
1319 } else { 1312 } else {
1320 HCheckMaps* check_cow_map = HCheckMaps::New( 1313 HCheckMaps* check_cow_map = HCheckMaps::New(
1321 elements, isolate()->factory()->fixed_array_map(), zone); 1314 elements, isolate()->factory()->fixed_array_map(), zone);
(...skipping 5945 matching lines...) Expand 10 before | Expand all | Expand 10 after
7267 elements_kind <= LAST_ELEMENTS_KIND; 7260 elements_kind <= LAST_ELEMENTS_KIND;
7268 elements_kind = ElementsKind(elements_kind + 1)) { 7261 elements_kind = ElementsKind(elements_kind + 1)) {
7269 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some 7262 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some
7270 // code that's executed for all external array cases. 7263 // code that's executed for all external array cases.
7271 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == 7264 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
7272 LAST_ELEMENTS_KIND); 7265 LAST_ELEMENTS_KIND);
7273 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND 7266 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
7274 && todo_external_array) { 7267 && todo_external_array) {
7275 HInstruction* length = 7268 HInstruction* length =
7276 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 7269 AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
7277 checked_key = AddBoundsCheck(key, length); 7270 checked_key = Add<HBoundsCheck>(key, length);
7278 external_elements = new(zone()) HLoadExternalArrayPointer(elements); 7271 external_elements = new(zone()) HLoadExternalArrayPointer(elements);
7279 AddInstruction(external_elements); 7272 AddInstruction(external_elements);
7280 } 7273 }
7281 if (type_todo[elements_kind]) { 7274 if (type_todo[elements_kind]) {
7282 HBasicBlock* if_true = graph()->CreateBasicBlock(); 7275 HBasicBlock* if_true = graph()->CreateBasicBlock();
7283 HBasicBlock* if_false = graph()->CreateBasicBlock(); 7276 HBasicBlock* if_false = graph()->CreateBasicBlock();
7284 HCompareConstantEqAndBranch* elements_kind_branch = 7277 HCompareConstantEqAndBranch* elements_kind_branch =
7285 new(zone()) HCompareConstantEqAndBranch( 7278 new(zone()) HCompareConstantEqAndBranch(
7286 elements_kind_instr, elements_kind, Token::EQ_STRICT); 7279 elements_kind_instr, elements_kind, Token::EQ_STRICT);
7287 elements_kind_branch->SetSuccessorAt(0, if_true); 7280 elements_kind_branch->SetSuccessorAt(0, if_true);
(...skipping 22 matching lines...) Expand all
7310 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 7303 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
7311 typecheck->SetSuccessorAt(0, if_jsarray); 7304 typecheck->SetSuccessorAt(0, if_jsarray);
7312 typecheck->SetSuccessorAt(1, if_fastobject); 7305 typecheck->SetSuccessorAt(1, if_fastobject);
7313 current_block()->Finish(typecheck); 7306 current_block()->Finish(typecheck);
7314 7307
7315 set_current_block(if_jsarray); 7308 set_current_block(if_jsarray);
7316 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), 7309 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(),
7317 typecheck, Representation::Smi()); 7310 typecheck, Representation::Smi());
7318 length->set_type(HType::Smi()); 7311 length->set_type(HType::Smi());
7319 7312
7320 checked_key = AddBoundsCheck(key, length); 7313 checked_key = Add<HBoundsCheck>(key, length);
7321 access = AddInstruction(BuildFastElementAccess( 7314 access = AddInstruction(BuildFastElementAccess(
7322 elements, checked_key, val, elements_kind_branch, 7315 elements, checked_key, val, elements_kind_branch,
7323 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); 7316 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
7324 if (!is_store) { 7317 if (!is_store) {
7325 Push(access); 7318 Push(access);
7326 } 7319 }
7327 7320
7328 *has_side_effects |= access->HasObservableSideEffects(); 7321 *has_side_effects |= access->HasObservableSideEffects();
7329 // The caller will use has_side_effects and add correct Simulate. 7322 // The caller will use has_side_effects and add correct Simulate.
7330 access->SetFlag(HValue::kHasNoObservableSideEffects); 7323 access->SetFlag(HValue::kHasNoObservableSideEffects);
7331 if (position != -1) { 7324 if (position != -1) {
7332 access->set_position(position); 7325 access->set_position(position);
7333 } 7326 }
7334 if_jsarray->GotoNoSimulate(join); 7327 if_jsarray->GotoNoSimulate(join);
7335 7328
7336 set_current_block(if_fastobject); 7329 set_current_block(if_fastobject);
7337 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 7330 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
7338 checked_key = AddBoundsCheck(key, length); 7331 checked_key = Add<HBoundsCheck>(key, length);
7339 access = AddInstruction(BuildFastElementAccess( 7332 access = AddInstruction(BuildFastElementAccess(
7340 elements, checked_key, val, elements_kind_branch, 7333 elements, checked_key, val, elements_kind_branch,
7341 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); 7334 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
7342 } else if (elements_kind == DICTIONARY_ELEMENTS) { 7335 } else if (elements_kind == DICTIONARY_ELEMENTS) {
7343 if (is_store) { 7336 if (is_store) {
7344 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 7337 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
7345 } else { 7338 } else {
7346 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 7339 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
7347 } 7340 }
7348 } else { // External array elements. 7341 } else { // External array elements.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
7480 Push(graph()->GetArgumentsObject()); 7473 Push(graph()->GetArgumentsObject());
7481 VisitForValue(expr->key()); 7474 VisitForValue(expr->key());
7482 if (HasStackOverflow() || current_block() == NULL) return true; 7475 if (HasStackOverflow() || current_block() == NULL) return true;
7483 HValue* key = Pop(); 7476 HValue* key = Pop();
7484 Drop(1); // Arguments object. 7477 Drop(1); // Arguments object.
7485 if (function_state()->outer() == NULL) { 7478 if (function_state()->outer() == NULL) {
7486 HInstruction* elements = AddInstruction( 7479 HInstruction* elements = AddInstruction(
7487 new(zone()) HArgumentsElements(false)); 7480 new(zone()) HArgumentsElements(false));
7488 HInstruction* length = AddInstruction( 7481 HInstruction* length = AddInstruction(
7489 new(zone()) HArgumentsLength(elements)); 7482 new(zone()) HArgumentsLength(elements));
7490 HInstruction* checked_key = AddBoundsCheck(key, length); 7483 HInstruction* checked_key = Add<HBoundsCheck>(key, length);
7491 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 7484 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
7492 } else { 7485 } else {
7493 EnsureArgumentsArePushedForAccess(); 7486 EnsureArgumentsArePushedForAccess();
7494 7487
7495 // Number of arguments without receiver. 7488 // Number of arguments without receiver.
7496 HInstruction* elements = function_state()->arguments_elements(); 7489 HInstruction* elements = function_state()->arguments_elements();
7497 int argument_count = environment()-> 7490 int argument_count = environment()->
7498 arguments_environment()->parameter_count() - 1; 7491 arguments_environment()->parameter_count() - 1;
7499 HInstruction* length = AddInstruction(new(zone()) HConstant( 7492 HInstruction* length = AddInstruction(new(zone()) HConstant(
7500 argument_count)); 7493 argument_count));
7501 HInstruction* checked_key = AddBoundsCheck(key, length); 7494 HInstruction* checked_key = Add<HBoundsCheck>(key, length);
7502 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 7495 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
7503 } 7496 }
7504 } 7497 }
7505 ast_context()->ReturnInstruction(result, expr->id()); 7498 ast_context()->ReturnInstruction(result, expr->id());
7506 return true; 7499 return true;
7507 } 7500 }
7508 7501
7509 7502
7510 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 7503 void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
7511 ASSERT(!HasStackOverflow()); 7504 ASSERT(!HasStackOverflow());
(...skipping 1804 matching lines...) Expand 10 before | Expand all | Expand 10 after
9316 if (i < 0 || i >= s->length()) { 9309 if (i < 0 || i >= s->length()) {
9317 return new(zone()) HConstant(OS::nan_value()); 9310 return new(zone()) HConstant(OS::nan_value());
9318 } 9311 }
9319 return new(zone()) HConstant(s->Get(i)); 9312 return new(zone()) HConstant(s->Get(i));
9320 } 9313 }
9321 } 9314 }
9322 BuildCheckHeapObject(string); 9315 BuildCheckHeapObject(string);
9323 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 9316 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
9324 HInstruction* length = HStringLength::New(zone(), string); 9317 HInstruction* length = HStringLength::New(zone(), string);
9325 AddInstruction(length); 9318 AddInstruction(length);
9326 HInstruction* checked_index = AddBoundsCheck(index, length); 9319 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
9327 return new(zone()) HStringCharCodeAt(context, string, checked_index); 9320 return new(zone()) HStringCharCodeAt(context, string, checked_index);
9328 } 9321 }
9329 9322
9330 // Checks if the given shift amounts have form: (sa) and (32 - sa). 9323 // Checks if the given shift amounts have form: (sa) and (32 - sa).
9331 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 9324 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
9332 HValue* const32_minus_sa) { 9325 HValue* const32_minus_sa) {
9333 if (!const32_minus_sa->IsSub()) return false; 9326 if (!const32_minus_sa->IsSub()) return false;
9334 HSub* sub = HSub::cast(const32_minus_sa); 9327 HSub* sub = HSub::cast(const32_minus_sa);
9335 if (sa != sub->right()) return false; 9328 if (sa != sub->right()) return false;
9336 HValue* const32 = sub->left(); 9329 HValue* const32 = sub->left();
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after
10530 // Our implementation of arguments (based on this stack frame or an 10523 // Our implementation of arguments (based on this stack frame or an
10531 // adapter below it) does not work for inlined functions. This runtime 10524 // adapter below it) does not work for inlined functions. This runtime
10532 // function is blacklisted by AstNode::IsInlineable. 10525 // function is blacklisted by AstNode::IsInlineable.
10533 ASSERT(function_state()->outer() == NULL); 10526 ASSERT(function_state()->outer() == NULL);
10534 ASSERT(call->arguments()->length() == 1); 10527 ASSERT(call->arguments()->length() == 1);
10535 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10528 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10536 HValue* index = Pop(); 10529 HValue* index = Pop();
10537 HInstruction* elements = AddInstruction( 10530 HInstruction* elements = AddInstruction(
10538 new(zone()) HArgumentsElements(false)); 10531 new(zone()) HArgumentsElements(false));
10539 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 10532 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
10540 HInstruction* checked_index = AddBoundsCheck(index, length); 10533 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
10541 HAccessArgumentsAt* result = 10534 HAccessArgumentsAt* result =
10542 new(zone()) HAccessArgumentsAt(elements, length, checked_index); 10535 new(zone()) HAccessArgumentsAt(elements, length, checked_index);
10543 return ast_context()->ReturnInstruction(result, call->id()); 10536 return ast_context()->ReturnInstruction(result, call->id());
10544 } 10537 }
10545 10538
10546 10539
10547 // Support for accessing the class and value fields of an object. 10540 // Support for accessing the class and value fields of an object.
10548 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 10541 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) {
10549 // The special form detected by IsClassOfTest is detected before we get here 10542 // The special form detected by IsClassOfTest is detected before we get here
10550 // and does not cause a bailout. 10543 // and does not cause a bailout.
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
11538 if (ShouldProduceTraceOutput()) { 11531 if (ShouldProduceTraceOutput()) {
11539 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11532 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11540 } 11533 }
11541 11534
11542 #ifdef DEBUG 11535 #ifdef DEBUG
11543 graph_->Verify(false); // No full verify. 11536 graph_->Verify(false); // No full verify.
11544 #endif 11537 #endif
11545 } 11538 }
11546 11539
11547 } } // namespace v8::internal 11540 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698