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

Side by Side Diff: src/hydrogen.cc

Issue 1107843002: Reland "Remove the weak list of views from array buffers" (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use bounds check Created 5 years, 7 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/hydrogen.h ('k') | src/hydrogen-instructions.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 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 2416 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 IsFixedTypedArrayElementsKind(elements_kind)) { 2427 IsFixedTypedArrayElementsKind(elements_kind)) {
2428 HValue* backing_store; 2428 HValue* backing_store;
2429 if (IsExternalArrayElementsKind(elements_kind)) { 2429 if (IsExternalArrayElementsKind(elements_kind)) {
2430 backing_store = Add<HLoadNamedField>( 2430 backing_store = Add<HLoadNamedField>(
2431 elements, nullptr, HObjectAccess::ForExternalArrayExternalPointer()); 2431 elements, nullptr, HObjectAccess::ForExternalArrayExternalPointer());
2432 } else { 2432 } else {
2433 backing_store = elements; 2433 backing_store = elements;
2434 } 2434 }
2435 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 2435 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
2436 NoObservableSideEffectsScope no_effects(this); 2436 NoObservableSideEffectsScope no_effects(this);
2437 if (IsExternalArrayElementsKind(elements_kind)) {
2438 HInstruction* buffer =
2439 Add<HLoadNamedField>(checked_object, nullptr,
2440 HObjectAccess::ForJSArrayBufferViewBuffer());
2441 HInstruction* flags = Add<HLoadNamedField>(
2442 buffer, nullptr, HObjectAccess::ForJSArrayBufferFlag());
2443 HValue* was_neutered_mask =
2444 Add<HConstant>(1 << JSArrayBuffer::kWasNeuteredBit);
2445 HValue* was_neutered_test =
2446 AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask);
2447
2448 IfBuilder if_was_neutered(this);
2449 if_was_neutered.If<HCompareNumericAndBranch>(
2450 was_neutered_test, graph()->GetConstant0(), Token::NE);
2451 if_was_neutered.ThenDeopt(Deoptimizer::kOutOfBounds);
2452 if_was_neutered.End();
2453 }
2437 IfBuilder length_checker(this); 2454 IfBuilder length_checker(this);
2438 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2455 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
2439 length_checker.Then(); 2456 length_checker.Then();
2440 IfBuilder negative_checker(this); 2457 IfBuilder negative_checker(this);
2441 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2458 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
2442 key, graph()->GetConstant0(), Token::GTE); 2459 key, graph()->GetConstant0(), Token::GTE);
2443 negative_checker.Then(); 2460 negative_checker.Then();
2444 HInstruction* result = AddElementAccess( 2461 HInstruction* result = AddElementAccess(
2445 backing_store, key, val, bounds_check, elements_kind, access_type); 2462 backing_store, key, val, bounds_check, elements_kind, access_type);
2446 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); 2463 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered);
2447 negative_checker.End(); 2464 negative_checker.End();
2448 length_checker.End(); 2465 length_checker.End();
2449 return result; 2466 return result;
2450 } else { 2467 } else {
2468 if (IsExternalArrayElementsKind(elements_kind)) {
2469 HInstruction* buffer =
2470 Add<HLoadNamedField>(checked_object, nullptr,
2471 HObjectAccess::ForJSArrayBufferViewBuffer());
2472 HInstruction* buffer_length = Add<HLoadNamedField>(
2473 buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength());
2474 Add<HBoundsCheck>(graph()->GetConstant0(), buffer_length);
2475 }
2451 DCHECK(store_mode == STANDARD_STORE); 2476 DCHECK(store_mode == STANDARD_STORE);
2452 checked_key = Add<HBoundsCheck>(key, length); 2477 checked_key = Add<HBoundsCheck>(key, length);
2453 return AddElementAccess( 2478 return AddElementAccess(
2454 backing_store, checked_key, val, 2479 backing_store, checked_key, val,
2455 checked_object, elements_kind, access_type); 2480 checked_object, elements_kind, access_type);
2456 } 2481 }
2457 } 2482 }
2458 DCHECK(fast_smi_only_elements || 2483 DCHECK(fast_smi_only_elements ||
2459 fast_elements || 2484 fast_elements ||
2460 IsFastDoubleElementsKind(elements_kind)); 2485 IsFastDoubleElementsKind(elements_kind));
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
3148 3173
3149 3174
3150 HInstruction* HGraphBuilder::BuildGetArrayFunction() { 3175 HInstruction* HGraphBuilder::BuildGetArrayFunction() {
3151 HInstruction* native_context = BuildGetNativeContext(); 3176 HInstruction* native_context = BuildGetNativeContext();
3152 HInstruction* index = 3177 HInstruction* index =
3153 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); 3178 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX));
3154 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); 3179 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS);
3155 } 3180 }
3156 3181
3157 3182
3183 HValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object,
3184 HValue* checked_object,
3185 FieldIndex index) {
3186 NoObservableSideEffectsScope scope(this);
3187 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
3188 index.offset(), Representation::Tagged());
3189 HInstruction* buffer = Add<HLoadNamedField>(
3190 object, checked_object, HObjectAccess::ForJSArrayBufferViewBuffer());
3191 HInstruction* field = Add<HLoadNamedField>(object, checked_object, access);
3192
3193 IfBuilder if_has_buffer(this);
3194 HValue* has_buffer = if_has_buffer.IfNot<HIsSmiAndBranch>(buffer);
3195 if_has_buffer.Then();
3196 {
3197 HInstruction* flags = Add<HLoadNamedField>(
3198 buffer, has_buffer, HObjectAccess::ForJSArrayBufferFlag());
3199 HValue* was_neutered_mask =
3200 Add<HConstant>(1 << JSArrayBuffer::kWasNeuteredBit);
3201 HValue* was_neutered_test =
3202 AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask);
3203
3204 IfBuilder if_was_neutered(this);
3205 if_was_neutered.If<HCompareNumericAndBranch>(
3206 was_neutered_test, graph()->GetConstant0(), Token::NE);
3207 if_was_neutered.Then();
3208 Push(graph()->GetConstant0());
3209 if_was_neutered.Else();
3210 Push(field);
3211 if_was_neutered.End();
3212 }
3213 if_has_buffer.Else();
3214 Push(field);
3215 if_has_buffer.End();
3216
3217 return Pop();
3218 }
3219
3220
3158 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 3221 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
3159 ElementsKind kind, 3222 ElementsKind kind,
3160 HValue* allocation_site_payload, 3223 HValue* allocation_site_payload,
3161 HValue* constructor_function, 3224 HValue* constructor_function,
3162 AllocationSiteOverrideMode override_mode) : 3225 AllocationSiteOverrideMode override_mode) :
3163 builder_(builder), 3226 builder_(builder),
3164 kind_(kind), 3227 kind_(kind),
3165 allocation_site_payload_(allocation_site_payload), 3228 allocation_site_payload_(allocation_site_payload),
3166 constructor_function_(constructor_function) { 3229 constructor_function_(constructor_function) {
3167 DCHECK(!allocation_site_payload->IsConstant() || 3230 DCHECK(!allocation_site_payload->IsConstant() ||
(...skipping 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after
5647 Handle<Symbol> sym = isolate()->factory()->home_object_symbol(); 5710 Handle<Symbol> sym = isolate()->factory()->home_object_symbol();
5648 HInstruction* store_home = BuildKeyedGeneric( 5711 HInstruction* store_home = BuildKeyedGeneric(
5649 STORE, NULL, value, Add<HConstant>(sym), literal); 5712 STORE, NULL, value, Add<HConstant>(sym), literal);
5650 AddInstruction(store_home); 5713 AddInstruction(store_home);
5651 DCHECK(store_home->HasObservableSideEffects()); 5714 DCHECK(store_home->HasObservableSideEffects());
5652 Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE); 5715 Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE);
5653 } 5716 }
5654 5717
5655 Handle<Map> map = property->GetReceiverType(); 5718 Handle<Map> map = property->GetReceiverType();
5656 Handle<String> name = key->AsPropertyName(); 5719 Handle<String> name = key->AsPropertyName();
5657 HInstruction* store; 5720 HValue* store;
5658 if (map.is_null()) { 5721 if (map.is_null()) {
5659 // If we don't know the monomorphic type, do a generic store. 5722 // If we don't know the monomorphic type, do a generic store.
5660 CHECK_ALIVE(store = BuildNamedGeneric( 5723 CHECK_ALIVE(store = BuildNamedGeneric(
5661 STORE, NULL, literal, name, value)); 5724 STORE, NULL, literal, name, value));
5662 } else { 5725 } else {
5663 PropertyAccessInfo info(this, STORE, map, name); 5726 PropertyAccessInfo info(this, STORE, map, name);
5664 if (info.CanAccessMonomorphic()) { 5727 if (info.CanAccessMonomorphic()) {
5665 HValue* checked_literal = Add<HCheckMaps>(literal, map); 5728 HValue* checked_literal = Add<HCheckMaps>(literal, map);
5666 DCHECK(!info.IsAccessorConstant()); 5729 DCHECK(!info.IsAccessorConstant());
5667 store = BuildMonomorphicAccess( 5730 store = BuildMonomorphicAccess(
5668 &info, literal, checked_literal, value, 5731 &info, literal, checked_literal, value,
5669 BailoutId::None(), BailoutId::None()); 5732 BailoutId::None(), BailoutId::None());
5670 } else { 5733 } else {
5671 CHECK_ALIVE(store = BuildNamedGeneric( 5734 CHECK_ALIVE(store = BuildNamedGeneric(
5672 STORE, NULL, literal, name, value)); 5735 STORE, NULL, literal, name, value));
5673 } 5736 }
5674 } 5737 }
5675 AddInstruction(store); 5738 if (store->IsInstruction()) {
5739 AddInstruction(HInstruction::cast(store));
5740 }
5676 DCHECK(store->HasObservableSideEffects()); 5741 DCHECK(store->HasObservableSideEffects());
5677 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5742 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5678 } else { 5743 } else {
5679 CHECK_ALIVE(VisitForEffect(value)); 5744 CHECK_ALIVE(VisitForEffect(value));
5680 } 5745 }
5681 break; 5746 break;
5682 } 5747 }
5683 // Fall through. 5748 // Fall through.
5684 case ObjectLiteral::Property::PROTOTYPE: 5749 case ObjectLiteral::Property::PROTOTYPE:
5685 case ObjectLiteral::Property::SETTER: 5750 case ObjectLiteral::Property::SETTER:
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
6126 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsIntegerIndexedExotic() { 6191 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsIntegerIndexedExotic() {
6127 InstanceType instance_type = map_->instance_type(); 6192 InstanceType instance_type = map_->instance_type();
6128 return instance_type == JS_TYPED_ARRAY_TYPE && 6193 return instance_type == JS_TYPED_ARRAY_TYPE &&
6129 IsSpecialIndex(isolate()->unicode_cache(), *name_); 6194 IsSpecialIndex(isolate()->unicode_cache(), *name_);
6130 } 6195 }
6131 6196
6132 6197
6133 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { 6198 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
6134 if (!CanInlinePropertyAccess(map_)) return false; 6199 if (!CanInlinePropertyAccess(map_)) return false;
6135 if (IsJSObjectFieldAccessor()) return IsLoad(); 6200 if (IsJSObjectFieldAccessor()) return IsLoad();
6201 if (IsJSArrayBufferViewFieldAccessor()) return IsLoad();
6136 if (map_->function_with_prototype() && !map_->has_non_instance_prototype() && 6202 if (map_->function_with_prototype() && !map_->has_non_instance_prototype() &&
6137 name_.is_identical_to(isolate()->factory()->prototype_string())) { 6203 name_.is_identical_to(isolate()->factory()->prototype_string())) {
6138 return IsLoad(); 6204 return IsLoad();
6139 } 6205 }
6140 if (!LookupDescriptor()) return false; 6206 if (!LookupDescriptor()) return false;
6141 if (IsFound()) return IsLoad() || !IsReadOnly(); 6207 if (IsFound()) return IsLoad() || !IsReadOnly();
6142 if (IsIntegerIndexedExotic()) return false; 6208 if (IsIntegerIndexedExotic()) return false;
6143 if (!LookupInPrototypes()) return false; 6209 if (!LookupInPrototypes()) return false;
6144 if (IsLoad()) return true; 6210 if (IsLoad()) return true;
6145 6211
(...skipping 28 matching lines...) Expand all
6174 if (GetJSObjectFieldAccess(&access)) { 6240 if (GetJSObjectFieldAccess(&access)) {
6175 for (int i = 1; i < maps->length(); ++i) { 6241 for (int i = 1; i < maps->length(); ++i) {
6176 PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_); 6242 PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_);
6177 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default 6243 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default
6178 if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; 6244 if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
6179 if (!access.Equals(test_access)) return false; 6245 if (!access.Equals(test_access)) return false;
6180 } 6246 }
6181 return true; 6247 return true;
6182 } 6248 }
6183 6249
6250 if (GetJSArrayBufferViewFieldAccess(&access)) {
6251 for (int i = 1; i < maps->length(); ++i) {
6252 PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_);
6253 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default
6254 if (!test_info.GetJSArrayBufferViewFieldAccess(&test_access)) {
6255 return false;
6256 }
6257 if (!access.Equals(test_access)) return false;
6258 }
6259 return true;
6260 }
6261
6184 // Currently only handle numbers as a polymorphic case. 6262 // Currently only handle numbers as a polymorphic case.
6185 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 6263 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
6186 // instruction. 6264 // instruction.
6187 if (IsNumberType()) return false; 6265 if (IsNumberType()) return false;
6188 6266
6189 // Multiple maps cannot transition to the same target map. 6267 // Multiple maps cannot transition to the same target map.
6190 DCHECK(!IsLoad() || !IsTransition()); 6268 DCHECK(!IsLoad() || !IsTransition());
6191 if (IsTransition() && maps->length() > 1) return false; 6269 if (IsTransition() && maps->length() > 1) return false;
6192 6270
6193 for (int i = 1; i < maps->length(); ++i) { 6271 for (int i = 1; i < maps->length(); ++i) {
(...skipping 19 matching lines...) Expand all
6213 !target->shared()->native(); 6291 !target->shared()->native();
6214 } 6292 }
6215 6293
6216 6294
6217 bool HOptimizedGraphBuilder::PropertyAccessInfo::NeedsWrappingFor( 6295 bool HOptimizedGraphBuilder::PropertyAccessInfo::NeedsWrappingFor(
6218 Handle<JSFunction> target) const { 6296 Handle<JSFunction> target) const {
6219 return NeedsWrapping(map_, target); 6297 return NeedsWrapping(map_, target);
6220 } 6298 }
6221 6299
6222 6300
6223 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( 6301 HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess(
6224 PropertyAccessInfo* info, 6302 PropertyAccessInfo* info, HValue* object, HValue* checked_object,
6225 HValue* object, 6303 HValue* value, BailoutId ast_id, BailoutId return_id,
6226 HValue* checked_object,
6227 HValue* value,
6228 BailoutId ast_id,
6229 BailoutId return_id,
6230 bool can_inline_accessor) { 6304 bool can_inline_accessor) {
6231
6232 HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6305 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
6233 if (info->GetJSObjectFieldAccess(&access)) { 6306 if (info->GetJSObjectFieldAccess(&access)) {
6234 DCHECK(info->IsLoad()); 6307 DCHECK(info->IsLoad());
6235 return New<HLoadNamedField>(object, checked_object, access); 6308 return New<HLoadNamedField>(object, checked_object, access);
6236 } 6309 }
6237 6310
6311 if (info->GetJSArrayBufferViewFieldAccess(&access)) {
6312 DCHECK(info->IsLoad());
6313 return BuildArrayBufferViewFieldAccessor(
6314 object, checked_object, FieldIndex::ForInObjectOffset(access.offset()));
6315 }
6316
6238 if (info->name().is_identical_to(isolate()->factory()->prototype_string()) && 6317 if (info->name().is_identical_to(isolate()->factory()->prototype_string()) &&
6239 info->map()->function_with_prototype()) { 6318 info->map()->function_with_prototype()) {
6240 DCHECK(!info->map()->has_non_instance_prototype()); 6319 DCHECK(!info->map()->has_non_instance_prototype());
6241 return New<HLoadFunctionPrototype>(checked_object); 6320 return New<HLoadFunctionPrototype>(checked_object);
6242 } 6321 }
6243 6322
6244 HValue* checked_holder = checked_object; 6323 HValue* checked_holder = checked_object;
6245 if (info->has_holder()) { 6324 if (info->has_holder()) {
6246 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 6325 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
6247 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 6326 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
6377 } 6456 }
6378 FinishCurrentBlock(compare); 6457 FinishCurrentBlock(compare);
6379 6458
6380 if (info.IsNumberType()) { 6459 if (info.IsNumberType()) {
6381 GotoNoSimulate(if_true, number_block); 6460 GotoNoSimulate(if_true, number_block);
6382 if_true = number_block; 6461 if_true = number_block;
6383 } 6462 }
6384 6463
6385 set_current_block(if_true); 6464 set_current_block(if_true);
6386 6465
6387 HInstruction* access = BuildMonomorphicAccess( 6466 HValue* access =
6388 &info, object, dependency, value, ast_id, 6467 BuildMonomorphicAccess(&info, object, dependency, value, ast_id,
6389 return_id, FLAG_polymorphic_inlining); 6468 return_id, FLAG_polymorphic_inlining);
6390 6469
6391 HValue* result = NULL; 6470 HValue* result = NULL;
6392 switch (access_type) { 6471 switch (access_type) {
6393 case LOAD: 6472 case LOAD:
6394 result = access; 6473 result = access;
6395 break; 6474 break;
6396 case STORE: 6475 case STORE:
6397 result = value; 6476 result = value;
6398 break; 6477 break;
6399 } 6478 }
6400 6479
6401 if (access == NULL) { 6480 if (access == NULL) {
6402 if (HasStackOverflow()) return; 6481 if (HasStackOverflow()) return;
6403 } else { 6482 } else {
6404 if (!access->IsLinked()) AddInstruction(access); 6483 if (access->IsInstruction()) {
6484 HInstruction* instr = HInstruction::cast(access);
6485 if (!instr->IsLinked()) AddInstruction(instr);
6486 }
6405 if (!ast_context()->IsEffect()) Push(result); 6487 if (!ast_context()->IsEffect()) Push(result);
6406 } 6488 }
6407 6489
6408 if (current_block() != NULL) Goto(join); 6490 if (current_block() != NULL) Goto(join);
6409 set_current_block(if_false); 6491 set_current_block(if_false);
6410 } 6492 }
6411 6493
6412 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6494 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6413 // know about and do not want to handle ones we've never seen. Otherwise 6495 // know about and do not want to handle ones we've never seen. Otherwise
6414 // use a generic IC. 6496 // use a generic IC.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
6488 } 6570 }
6489 6571
6490 // Named store. 6572 // Named store.
6491 HValue* value = Pop(); 6573 HValue* value = Pop();
6492 HValue* object = Pop(); 6574 HValue* object = Pop();
6493 6575
6494 Literal* key = prop->key()->AsLiteral(); 6576 Literal* key = prop->key()->AsLiteral();
6495 Handle<String> name = Handle<String>::cast(key->value()); 6577 Handle<String> name = Handle<String>::cast(key->value());
6496 DCHECK(!name.is_null()); 6578 DCHECK(!name.is_null());
6497 6579
6498 HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr, 6580 HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, object,
6499 object, name, value, is_uninitialized); 6581 name, value, is_uninitialized);
6500 if (instr == NULL) return; 6582 if (access == NULL) return;
6501 6583
6502 if (!ast_context()->IsEffect()) Push(value); 6584 if (!ast_context()->IsEffect()) Push(value);
6503 AddInstruction(instr); 6585 if (access->IsInstruction()) AddInstruction(HInstruction::cast(access));
6504 if (instr->HasObservableSideEffects()) { 6586 if (access->HasObservableSideEffects()) {
6505 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6587 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6506 } 6588 }
6507 if (!ast_context()->IsEffect()) Drop(1); 6589 if (!ast_context()->IsEffect()) Drop(1);
6508 return ast_context()->ReturnValue(value); 6590 return ast_context()->ReturnValue(value);
6509 } 6591 }
6510 6592
6511 6593
6512 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6594 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6513 Property* prop = expr->target()->AsProperty(); 6595 Property* prop = expr->target()->AsProperty();
6514 DCHECK(prop != NULL); 6596 DCHECK(prop != NULL);
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
7250 if (key->ActualValue()->IsConstant()) { 7332 if (key->ActualValue()->IsConstant()) {
7251 Handle<Object> constant = 7333 Handle<Object> constant =
7252 HConstant::cast(key->ActualValue())->handle(isolate()); 7334 HConstant::cast(key->ActualValue())->handle(isolate());
7253 uint32_t array_index; 7335 uint32_t array_index;
7254 if (constant->IsString() && 7336 if (constant->IsString() &&
7255 !Handle<String>::cast(constant)->AsArrayIndex(&array_index)) { 7337 !Handle<String>::cast(constant)->AsArrayIndex(&array_index)) {
7256 if (!constant->IsUniqueName()) { 7338 if (!constant->IsUniqueName()) {
7257 constant = isolate()->factory()->InternalizeString( 7339 constant = isolate()->factory()->InternalizeString(
7258 Handle<String>::cast(constant)); 7340 Handle<String>::cast(constant));
7259 } 7341 }
7260 HInstruction* instr = 7342 HValue* access =
7261 BuildNamedAccess(access_type, ast_id, return_id, expr, obj, 7343 BuildNamedAccess(access_type, ast_id, return_id, expr, obj,
7262 Handle<String>::cast(constant), val, false); 7344 Handle<String>::cast(constant), val, false);
7263 if (instr == NULL || instr->IsLinked()) { 7345 if (access == NULL || access->IsPhi() ||
7346 HInstruction::cast(access)->IsLinked()) {
7264 *has_side_effects = false; 7347 *has_side_effects = false;
7265 } else { 7348 } else {
7349 HInstruction* instr = HInstruction::cast(access);
7266 AddInstruction(instr); 7350 AddInstruction(instr);
7267 *has_side_effects = instr->HasObservableSideEffects(); 7351 *has_side_effects = instr->HasObservableSideEffects();
7268 } 7352 }
7269 return instr; 7353 return access;
7270 } 7354 }
7271 } 7355 }
7272 7356
7273 DCHECK(!expr->IsPropertyName()); 7357 DCHECK(!expr->IsPropertyName());
7274 HInstruction* instr = NULL; 7358 HInstruction* instr = NULL;
7275 7359
7276 SmallMapList* maps; 7360 SmallMapList* maps;
7277 bool monomorphic = ComputeReceiverTypes(expr, obj, &maps, zone()); 7361 bool monomorphic = ComputeReceiverTypes(expr, obj, &maps, zone());
7278 7362
7279 bool force_generic = false; 7363 bool force_generic = false;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
7418 HInstruction* length = Add<HConstant>(argument_count); 7502 HInstruction* length = Add<HConstant>(argument_count);
7419 HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7503 HInstruction* checked_key = Add<HBoundsCheck>(key, length);
7420 result = New<HAccessArgumentsAt>(elements, length, checked_key); 7504 result = New<HAccessArgumentsAt>(elements, length, checked_key);
7421 } 7505 }
7422 } 7506 }
7423 ast_context()->ReturnInstruction(result, expr->id()); 7507 ast_context()->ReturnInstruction(result, expr->id());
7424 return true; 7508 return true;
7425 } 7509 }
7426 7510
7427 7511
7428 HInstruction* HOptimizedGraphBuilder::BuildNamedAccess( 7512 HValue* HOptimizedGraphBuilder::BuildNamedAccess(
7429 PropertyAccessType access, 7513 PropertyAccessType access, BailoutId ast_id, BailoutId return_id,
7430 BailoutId ast_id, 7514 Expression* expr, HValue* object, Handle<String> name, HValue* value,
7431 BailoutId return_id,
7432 Expression* expr,
7433 HValue* object,
7434 Handle<String> name,
7435 HValue* value,
7436 bool is_uninitialized) { 7515 bool is_uninitialized) {
7437 SmallMapList* maps; 7516 SmallMapList* maps;
7438 ComputeReceiverTypes(expr, object, &maps, zone()); 7517 ComputeReceiverTypes(expr, object, &maps, zone());
7439 DCHECK(maps != NULL); 7518 DCHECK(maps != NULL);
7440 7519
7441 if (maps->length() > 0) { 7520 if (maps->length() > 0) {
7442 PropertyAccessInfo info(this, access, maps->first(), name); 7521 PropertyAccessInfo info(this, access, maps->first(), name);
7443 if (!info.CanAccessAsMonomorphic(maps)) { 7522 if (!info.CanAccessAsMonomorphic(maps)) {
7444 HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object, 7523 HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object,
7445 value, maps, name); 7524 value, maps, name);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
7481 HValue* index = Pop(); 7560 HValue* index = Pop();
7482 HValue* string = Pop(); 7561 HValue* string = Pop();
7483 HInstruction* char_code = BuildStringCharCodeAt(string, index); 7562 HInstruction* char_code = BuildStringCharCodeAt(string, index);
7484 AddInstruction(char_code); 7563 AddInstruction(char_code);
7485 instr = NewUncasted<HStringCharFromCode>(char_code); 7564 instr = NewUncasted<HStringCharFromCode>(char_code);
7486 7565
7487 } else if (expr->key()->IsPropertyName()) { 7566 } else if (expr->key()->IsPropertyName()) {
7488 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7567 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
7489 HValue* object = Pop(); 7568 HValue* object = Pop();
7490 7569
7491 instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, 7570 HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, object,
7492 object, name, NULL, expr->IsUninitialized()); 7571 name, NULL, expr->IsUninitialized());
7493 if (instr == NULL) return; 7572 if (value == NULL) return;
7573 if (value->IsPhi()) return ast_context()->ReturnValue(value);
7574 instr = HInstruction::cast(value);
7494 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 7575 if (instr->IsLinked()) return ast_context()->ReturnValue(instr);
7495 7576
7496 } else { 7577 } else {
7497 HValue* key = Pop(); 7578 HValue* key = Pop();
7498 HValue* obj = Pop(); 7579 HValue* obj = Pop();
7499 7580
7500 bool has_side_effects = false; 7581 bool has_side_effects = false;
7501 HValue* load = HandleKeyedElementAccess( 7582 HValue* load = HandleKeyedElementAccess(
7502 obj, key, NULL, expr, ast_id, expr->LoadId(), LOAD, &has_side_effects); 7583 obj, key, NULL, expr, ast_id, expr->LoadId(), LOAD, &has_side_effects);
7503 if (has_side_effects) { 7584 if (has_side_effects) {
(...skipping 2113 matching lines...) Expand 10 before | Expand all | Expand 10 after
9617 byte_offset); 9698 byte_offset);
9618 Add<HStoreNamedField>( 9699 Add<HStoreNamedField>(
9619 obj, 9700 obj,
9620 HObjectAccess::ForJSArrayBufferViewByteLength(), 9701 HObjectAccess::ForJSArrayBufferViewByteLength(),
9621 byte_length); 9702 byte_length);
9622 9703
9623 if (buffer != NULL) { 9704 if (buffer != NULL) {
9624 Add<HStoreNamedField>( 9705 Add<HStoreNamedField>(
9625 obj, 9706 obj,
9626 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); 9707 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
9627 HObjectAccess weak_first_view_access =
9628 HObjectAccess::ForJSArrayBufferWeakFirstView();
9629 Add<HStoreNamedField>(
9630 obj, HObjectAccess::ForJSArrayBufferViewWeakNext(),
9631 Add<HLoadNamedField>(buffer, nullptr, weak_first_view_access));
9632 Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
9633 } else { 9708 } else {
9634 Add<HStoreNamedField>( 9709 Add<HStoreNamedField>(
9635 obj, 9710 obj,
9636 HObjectAccess::ForJSArrayBufferViewBuffer(), 9711 HObjectAccess::ForJSArrayBufferViewBuffer(),
9637 Add<HConstant>(static_cast<int32_t>(0))); 9712 Add<HConstant>(static_cast<int32_t>(0)));
9638 Add<HStoreNamedField>(obj,
9639 HObjectAccess::ForJSArrayBufferViewWeakNext(),
9640 graph()->GetConstantUndefined());
9641 } 9713 }
9642 } 9714 }
9643 9715
9644 9716
9645 void HOptimizedGraphBuilder::GenerateDataViewInitialize( 9717 void HOptimizedGraphBuilder::GenerateDataViewInitialize(
9646 CallRuntime* expr) { 9718 CallRuntime* expr) {
9647 ZoneList<Expression*>* arguments = expr->arguments(); 9719 ZoneList<Expression*>* arguments = expr->arguments();
9648 9720
9649 DCHECK(arguments->length()== 4); 9721 DCHECK(arguments->length()== 4);
9650 CHECK_ALIVE(VisitForValue(arguments->at(0))); 9722 CHECK_ALIVE(VisitForValue(arguments->at(0)));
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
9926 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9998 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9927 HValue* buffer = Pop(); 9999 HValue* buffer = Pop();
9928 HInstruction* result = New<HLoadNamedField>( 10000 HInstruction* result = New<HLoadNamedField>(
9929 buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength()); 10001 buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength());
9930 return ast_context()->ReturnInstruction(result, expr->id()); 10002 return ast_context()->ReturnInstruction(result, expr->id());
9931 } 10003 }
9932 10004
9933 10005
9934 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( 10006 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength(
9935 CallRuntime* expr) { 10007 CallRuntime* expr) {
10008 NoObservableSideEffectsScope scope(this);
9936 DCHECK(expr->arguments()->length() == 1); 10009 DCHECK(expr->arguments()->length() == 1);
9937 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10010 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9938 HValue* buffer = Pop(); 10011 HValue* view = Pop();
9939 HInstruction* result = New<HLoadNamedField>( 10012
9940 buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteLength()); 10013 return ast_context()->ReturnValue(BuildArrayBufferViewFieldAccessor(
9941 return ast_context()->ReturnInstruction(result, expr->id()); 10014 view, nullptr,
10015 FieldIndex::ForInObjectOffset(JSArrayBufferView::kByteLengthOffset)));
9942 } 10016 }
9943 10017
9944 10018
9945 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( 10019 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
9946 CallRuntime* expr) { 10020 CallRuntime* expr) {
10021 NoObservableSideEffectsScope scope(this);
9947 DCHECK(expr->arguments()->length() == 1); 10022 DCHECK(expr->arguments()->length() == 1);
9948 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10023 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9949 HValue* buffer = Pop(); 10024 HValue* view = Pop();
9950 HInstruction* result = New<HLoadNamedField>( 10025
9951 buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteOffset()); 10026 return ast_context()->ReturnValue(BuildArrayBufferViewFieldAccessor(
9952 return ast_context()->ReturnInstruction(result, expr->id()); 10027 view, nullptr,
10028 FieldIndex::ForInObjectOffset(JSArrayBufferView::kByteOffsetOffset)));
9953 } 10029 }
9954 10030
9955 10031
9956 void HOptimizedGraphBuilder::GenerateTypedArrayGetLength( 10032 void HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
9957 CallRuntime* expr) { 10033 CallRuntime* expr) {
10034 NoObservableSideEffectsScope scope(this);
9958 DCHECK(expr->arguments()->length() == 1); 10035 DCHECK(expr->arguments()->length() == 1);
9959 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10036 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9960 HValue* buffer = Pop(); 10037 HValue* view = Pop();
9961 HInstruction* result = New<HLoadNamedField>( 10038
9962 buffer, nullptr, HObjectAccess::ForJSTypedArrayLength()); 10039 return ast_context()->ReturnValue(BuildArrayBufferViewFieldAccessor(
9963 return ast_context()->ReturnInstruction(result, expr->id()); 10040 view, nullptr,
10041 FieldIndex::ForInObjectOffset(JSTypedArray::kLengthOffset)));
9964 } 10042 }
9965 10043
9966 10044
9967 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 10045 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
9968 DCHECK(!HasStackOverflow()); 10046 DCHECK(!HasStackOverflow());
9969 DCHECK(current_block() != NULL); 10047 DCHECK(current_block() != NULL);
9970 DCHECK(current_block()->HasPredecessor()); 10048 DCHECK(current_block()->HasPredecessor());
9971 if (expr->is_jsruntime()) { 10049 if (expr->is_jsruntime()) {
9972 return Bailout(kCallToAJavaScriptRuntimeFunction); 10050 return Bailout(kCallToAJavaScriptRuntimeFunction);
9973 } 10051 }
(...skipping 3029 matching lines...) Expand 10 before | Expand all | Expand 10 after
13003 if (ShouldProduceTraceOutput()) { 13081 if (ShouldProduceTraceOutput()) {
13004 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13082 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13005 } 13083 }
13006 13084
13007 #ifdef DEBUG 13085 #ifdef DEBUG
13008 graph_->Verify(false); // No full verify. 13086 graph_->Verify(false); // No full verify.
13009 #endif 13087 #endif
13010 } 13088 }
13011 13089
13012 } } // namespace v8::internal 13090 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698