OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 4321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4332 if (store_value_as_double) { | 4332 if (store_value_as_double) { |
4333 StoreObjectFieldNoWriteBarrier(property_storage, offset, value, | 4333 StoreObjectFieldNoWriteBarrier(property_storage, offset, value, |
4334 MachineRepresentation::kFloat64); | 4334 MachineRepresentation::kFloat64); |
4335 } else if (representation.IsSmi()) { | 4335 } else if (representation.IsSmi()) { |
4336 StoreObjectFieldNoWriteBarrier(property_storage, offset, value); | 4336 StoreObjectFieldNoWriteBarrier(property_storage, offset, value); |
4337 } else { | 4337 } else { |
4338 StoreObjectField(property_storage, offset, value); | 4338 StoreObjectField(property_storage, offset, value); |
4339 } | 4339 } |
4340 } | 4340 } |
4341 | 4341 |
| 4342 Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key, |
| 4343 Node* value, Label* bailout) { |
| 4344 // Mapped arguments are actual arguments. Unmapped arguments are values added |
| 4345 // to the arguments object after it was created for the call. Mapped arguments |
| 4346 // are stored in the context at indexes given by elements[key + 2]. Unmapped |
| 4347 // arguments are stored as regular indexed properties in the arguments array, |
| 4348 // held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed |
| 4349 // look at argument object construction. |
| 4350 // |
| 4351 // The sloppy arguments elements array has a special format: |
| 4352 // |
| 4353 // 0: context |
| 4354 // 1: unmapped arguments array |
| 4355 // 2: mapped_index0, |
| 4356 // 3: mapped_index1, |
| 4357 // ... |
| 4358 // |
| 4359 // length is 2 + min(number_of_actual_arguments, number_of_formal_arguments). |
| 4360 // If key + 2 >= elements.length then attempt to look in the unmapped |
| 4361 // arguments array (given by elements[1]) and return the value at key, missing |
| 4362 // to the runtime if the unmapped arguments array is not a fixed array or if |
| 4363 // key >= unmapped_arguments_array.length. |
| 4364 // |
| 4365 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value |
| 4366 // in the unmapped arguments array, as described above. Otherwise, t is a Smi |
| 4367 // index into the context array given at elements[0]. Return the value at |
| 4368 // context[t]. |
| 4369 |
| 4370 bool is_load = value == nullptr; |
| 4371 |
| 4372 GotoUnless(WordIsSmi(key), bailout); |
| 4373 key = SmiUntag(key); |
| 4374 GotoIf(IntPtrLessThan(key, IntPtrConstant(0)), bailout); |
| 4375 |
| 4376 Node* elements = LoadElements(receiver); |
| 4377 Node* elements_length = LoadAndUntagFixedArrayBaseLength(elements); |
| 4378 |
| 4379 Variable var_result(this, MachineRepresentation::kTagged); |
| 4380 if (!is_load) { |
| 4381 var_result.Bind(value); |
| 4382 } |
| 4383 Label if_mapped(this), if_unmapped(this), end(this, &var_result); |
| 4384 Node* intptr_two = IntPtrConstant(2); |
| 4385 Node* adjusted_length = IntPtrSub(elements_length, intptr_two); |
| 4386 |
| 4387 GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped); |
| 4388 |
| 4389 Node* mapped_index = LoadFixedArrayElement( |
| 4390 elements, IntPtrAdd(key, intptr_two), 0, INTPTR_PARAMETERS); |
| 4391 Branch(WordEqual(mapped_index, TheHoleConstant()), &if_unmapped, &if_mapped); |
| 4392 |
| 4393 Bind(&if_mapped); |
| 4394 { |
| 4395 Assert(WordIsSmi(mapped_index)); |
| 4396 mapped_index = SmiUntag(mapped_index); |
| 4397 Node* the_context = LoadFixedArrayElement(elements, IntPtrConstant(0), 0, |
| 4398 INTPTR_PARAMETERS); |
| 4399 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); |
| 4400 if (is_load) { |
| 4401 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, |
| 4402 INTPTR_PARAMETERS); |
| 4403 Assert(WordNotEqual(result, TheHoleConstant())); |
| 4404 var_result.Bind(result); |
| 4405 } else { |
| 4406 StoreFixedArrayElement(the_context, mapped_index, value, |
| 4407 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); |
| 4408 } |
| 4409 Goto(&end); |
| 4410 } |
| 4411 |
| 4412 Bind(&if_unmapped); |
| 4413 { |
| 4414 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, |
| 4415 INTPTR_PARAMETERS); |
| 4416 GotoIf(WordNotEqual(LoadMap(backing_store), |
| 4417 LoadRoot(Heap::kFixedArrayMapRootIndex)), |
| 4418 bailout); |
| 4419 |
| 4420 Node* backing_store_length = |
| 4421 LoadAndUntagFixedArrayBaseLength(backing_store); |
| 4422 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout); |
| 4423 |
| 4424 // The key falls into unmapped range. |
| 4425 if (is_load) { |
| 4426 Node* result = |
| 4427 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS); |
| 4428 GotoIf(WordEqual(result, TheHoleConstant()), bailout); |
| 4429 var_result.Bind(result); |
| 4430 } else { |
| 4431 StoreFixedArrayElement(backing_store, key, value, UPDATE_WRITE_BARRIER, |
| 4432 INTPTR_PARAMETERS); |
| 4433 } |
| 4434 Goto(&end); |
| 4435 } |
| 4436 |
| 4437 Bind(&end); |
| 4438 return var_result.value(); |
| 4439 } |
| 4440 |
4342 Node* CodeStubAssembler::EnumLength(Node* map) { | 4441 Node* CodeStubAssembler::EnumLength(Node* map) { |
4343 Node* bitfield_3 = LoadMapBitField3(map); | 4442 Node* bitfield_3 = LoadMapBitField3(map); |
4344 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); | 4443 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); |
4345 return SmiTag(enum_length); | 4444 return SmiTag(enum_length); |
4346 } | 4445 } |
4347 | 4446 |
4348 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, | 4447 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, |
4349 Label* use_runtime) { | 4448 Label* use_runtime) { |
4350 Variable current_js_object(this, MachineRepresentation::kTagged); | 4449 Variable current_js_object(this, MachineRepresentation::kTagged); |
4351 current_js_object.Bind(receiver); | 4450 current_js_object.Bind(receiver); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4419 Heap::kTheHoleValueRootIndex); | 4518 Heap::kTheHoleValueRootIndex); |
4420 | 4519 |
4421 // Store the WeakCell in the feedback vector. | 4520 // Store the WeakCell in the feedback vector. |
4422 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 4521 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
4423 CodeStubAssembler::SMI_PARAMETERS); | 4522 CodeStubAssembler::SMI_PARAMETERS); |
4424 return cell; | 4523 return cell; |
4425 } | 4524 } |
4426 | 4525 |
4427 } // namespace internal | 4526 } // namespace internal |
4428 } // namespace v8 | 4527 } // namespace v8 |
OLD | NEW |