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) { | |
mvstanton
2016/09/13 07:23:05
I recognize it's a "straight port" but it would be
Igor Sheludko
2016/09/13 07:43:24
Done.
| |
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 |