Revision f230a1cf deps/v8/src/arm/stub-cache-arm.cc
deps/v8/src/arm/stub-cache-arm.cc | ||
---|---|---|
380 | 380 |
Register receiver, |
381 | 381 |
Register scratch1, |
382 | 382 |
Register scratch2, |
383 |
Label* miss, |
|
384 |
bool support_wrappers) { |
|
383 |
Label* miss) { |
|
385 | 384 |
Label check_wrapper; |
386 | 385 |
|
387 | 386 |
// Check if the object is a string leaving the instance type in the |
388 | 387 |
// scratch1 register. |
389 |
GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, |
|
390 |
support_wrappers ? &check_wrapper : miss); |
|
388 |
GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper); |
|
391 | 389 |
|
392 | 390 |
// Load length directly from the string. |
393 | 391 |
__ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset)); |
394 | 392 |
__ Ret(); |
395 | 393 |
|
396 |
if (support_wrappers) { |
|
397 |
// Check if the object is a JSValue wrapper. |
|
398 |
__ bind(&check_wrapper); |
|
399 |
__ cmp(scratch1, Operand(JS_VALUE_TYPE)); |
|
400 |
__ b(ne, miss); |
|
394 |
// Check if the object is a JSValue wrapper. |
|
395 |
__ bind(&check_wrapper); |
|
396 |
__ cmp(scratch1, Operand(JS_VALUE_TYPE)); |
|
397 |
__ b(ne, miss); |
|
401 | 398 |
|
402 |
// Unwrap the value and check if the wrapped value is a string. |
|
403 |
__ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset)); |
|
404 |
GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss); |
|
405 |
__ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset)); |
|
406 |
__ Ret(); |
|
407 |
} |
|
399 |
// Unwrap the value and check if the wrapped value is a string. |
|
400 |
__ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset)); |
|
401 |
GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss); |
|
402 |
__ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset)); |
|
403 |
__ Ret(); |
|
408 | 404 |
} |
409 | 405 |
|
410 | 406 |
|
... | ... | |
437 | 433 |
} |
438 | 434 |
|
439 | 435 |
|
440 |
void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
|
|
436 |
void StoreStubCompiler::GenerateNegativeHolderLookup( |
|
441 | 437 |
MacroAssembler* masm, |
442 | 438 |
Handle<JSObject> holder, |
443 | 439 |
Register holder_reg, |
... | ... | |
457 | 453 |
// When leaving generated code after success, the receiver_reg and name_reg |
458 | 454 |
// may be clobbered. Upon branch to miss_label, the receiver and name |
459 | 455 |
// registers have their original values. |
460 |
void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
|
|
461 |
Handle<JSObject> object,
|
|
462 |
LookupResult* lookup,
|
|
463 |
Handle<Map> transition,
|
|
464 |
Handle<Name> name,
|
|
465 |
Register receiver_reg,
|
|
466 |
Register storage_reg,
|
|
467 |
Register value_reg,
|
|
468 |
Register scratch1,
|
|
469 |
Register scratch2,
|
|
470 |
Register scratch3,
|
|
471 |
Label* miss_label,
|
|
472 |
Label* slow) {
|
|
456 |
void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
|
457 |
Handle<JSObject> object, |
|
458 |
LookupResult* lookup, |
|
459 |
Handle<Map> transition, |
|
460 |
Handle<Name> name, |
|
461 |
Register receiver_reg, |
|
462 |
Register storage_reg, |
|
463 |
Register value_reg, |
|
464 |
Register scratch1, |
|
465 |
Register scratch2, |
|
466 |
Register scratch3, |
|
467 |
Label* miss_label, |
|
468 |
Label* slow) { |
|
473 | 469 |
// r0 : value |
474 | 470 |
Label exit; |
475 | 471 |
|
... | ... | |
481 | 477 |
|
482 | 478 |
if (details.type() == CONSTANT) { |
483 | 479 |
Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); |
484 |
__ LoadObject(scratch1, constant);
|
|
480 |
__ Move(scratch1, constant);
|
|
485 | 481 |
__ cmp(value_reg, scratch1); |
486 | 482 |
__ b(ne, miss_label); |
487 | 483 |
} else if (FLAG_track_fields && representation.IsSmi()) { |
... | ... | |
621 | 617 |
// When leaving generated code after success, the receiver_reg and name_reg |
622 | 618 |
// may be clobbered. Upon branch to miss_label, the receiver and name |
623 | 619 |
// registers have their original values. |
624 |
void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
|
|
625 |
Handle<JSObject> object,
|
|
626 |
LookupResult* lookup,
|
|
627 |
Register receiver_reg,
|
|
628 |
Register name_reg,
|
|
629 |
Register value_reg,
|
|
630 |
Register scratch1,
|
|
631 |
Register scratch2,
|
|
632 |
Label* miss_label) {
|
|
620 |
void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, |
|
621 |
Handle<JSObject> object, |
|
622 |
LookupResult* lookup, |
|
623 |
Register receiver_reg, |
|
624 |
Register name_reg, |
|
625 |
Register value_reg, |
|
626 |
Register scratch1, |
|
627 |
Register scratch2, |
|
628 |
Label* miss_label) { |
|
633 | 629 |
// r0 : value |
634 | 630 |
Label exit; |
635 | 631 |
|
... | ... | |
740 | 736 |
} |
741 | 737 |
|
742 | 738 |
|
743 |
void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
|
|
744 |
Label* label,
|
|
745 |
Handle<Name> name) {
|
|
739 |
void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
|
740 |
Label* label, |
|
741 |
Handle<Name> name) { |
|
746 | 742 |
if (!label->is_unused()) { |
747 | 743 |
__ bind(label); |
748 | 744 |
__ mov(this->name(), Operand(name)); |
... | ... | |
843 | 839 |
|
844 | 840 |
static void GenerateFastApiDirectCall(MacroAssembler* masm, |
845 | 841 |
const CallOptimization& optimization, |
846 |
int argc) { |
|
842 |
int argc, |
|
843 |
bool restore_context) { |
|
847 | 844 |
// ----------- S t a t e ------------- |
848 |
// -- sp[0] : holder (set by CheckPrototypes) |
|
849 |
// -- sp[4] : callee JS function |
|
850 |
// -- sp[8] : call data |
|
851 |
// -- sp[12] : isolate |
|
852 |
// -- sp[16] : ReturnValue default value |
|
853 |
// -- sp[20] : ReturnValue |
|
854 |
// -- sp[24] : last JS argument |
|
845 |
// -- sp[0] - sp[24] : FunctionCallbackInfo, incl. |
|
846 |
// : holder (set by CheckPrototypes) |
|
847 |
// -- sp[28] : last JS argument |
|
855 | 848 |
// -- ... |
856 |
// -- sp[(argc + 5) * 4] : first JS argument
|
|
857 |
// -- sp[(argc + 6) * 4] : receiver
|
|
849 |
// -- sp[(argc + 6) * 4] : first JS argument
|
|
850 |
// -- sp[(argc + 7) * 4] : receiver
|
|
858 | 851 |
// ----------------------------------- |
852 |
typedef FunctionCallbackArguments FCA; |
|
853 |
// Save calling context. |
|
854 |
__ str(cp, MemOperand(sp, FCA::kContextSaveIndex * kPointerSize)); |
|
859 | 855 |
// Get the function and setup the context. |
860 | 856 |
Handle<JSFunction> function = optimization.constant_function(); |
861 |
__ LoadHeapObject(r5, function);
|
|
857 |
__ Move(r5, function);
|
|
862 | 858 |
__ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset)); |
859 |
__ str(r5, MemOperand(sp, FCA::kCalleeIndex * kPointerSize)); |
|
863 | 860 |
|
864 |
// Pass the additional arguments.
|
|
861 |
// Construct the FunctionCallbackInfo.
|
|
865 | 862 |
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
866 | 863 |
Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
867 | 864 |
if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
... | ... | |
870 | 867 |
} else { |
871 | 868 |
__ Move(r6, call_data); |
872 | 869 |
} |
873 |
__ mov(r7, Operand(ExternalReference::isolate_address(masm->isolate()))); |
|
874 |
// Store JS function, call data, isolate ReturnValue default and ReturnValue. |
|
875 |
__ stm(ib, sp, r5.bit() | r6.bit() | r7.bit()); |
|
870 |
// Store call data. |
|
871 |
__ str(r6, MemOperand(sp, FCA::kDataIndex * kPointerSize)); |
|
872 |
// Store isolate. |
|
873 |
__ mov(r5, Operand(ExternalReference::isolate_address(masm->isolate()))); |
|
874 |
__ str(r5, MemOperand(sp, FCA::kIsolateIndex * kPointerSize)); |
|
875 |
// Store ReturnValue default and ReturnValue. |
|
876 | 876 |
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
877 |
__ str(r5, MemOperand(sp, 4 * kPointerSize));
|
|
878 |
__ str(r5, MemOperand(sp, 5 * kPointerSize));
|
|
877 |
__ str(r5, MemOperand(sp, FCA::kReturnValueOffset * kPointerSize));
|
|
878 |
__ str(r5, MemOperand(sp, FCA::kReturnValueDefaultValueIndex * kPointerSize));
|
|
879 | 879 |
|
880 | 880 |
// Prepare arguments. |
881 |
__ add(r2, sp, Operand(5 * kPointerSize));
|
|
881 |
__ mov(r2, sp);
|
|
882 | 882 |
|
883 | 883 |
// Allocate the v8::Arguments structure in the arguments' space since |
884 | 884 |
// it's not controlled by GC. |
... | ... | |
887 | 887 |
FrameScope frame_scope(masm, StackFrame::MANUAL); |
888 | 888 |
__ EnterExitFrame(false, kApiStackSpace); |
889 | 889 |
|
890 |
// r0 = v8::Arguments&
|
|
890 |
// r0 = FunctionCallbackInfo&
|
|
891 | 891 |
// Arguments is after the return address. |
892 | 892 |
__ add(r0, sp, Operand(1 * kPointerSize)); |
893 |
// v8::Arguments::implicit_args_
|
|
893 |
// FunctionCallbackInfo::implicit_args_
|
|
894 | 894 |
__ str(r2, MemOperand(r0, 0 * kPointerSize)); |
895 |
// v8::Arguments::values_
|
|
896 |
__ add(ip, r2, Operand(argc * kPointerSize));
|
|
895 |
// FunctionCallbackInfo::values_
|
|
896 |
__ add(ip, r2, Operand((kFastApiCallArguments - 1 + argc) * kPointerSize));
|
|
897 | 897 |
__ str(ip, MemOperand(r0, 1 * kPointerSize)); |
898 |
// v8::Arguments::length_ = argc
|
|
898 |
// FunctionCallbackInfo::length_ = argc
|
|
899 | 899 |
__ mov(ip, Operand(argc)); |
900 | 900 |
__ str(ip, MemOperand(r0, 2 * kPointerSize)); |
901 |
// v8::Arguments::is_construct_call = 0
|
|
901 |
// FunctionCallbackInfo::is_construct_call = 0
|
|
902 | 902 |
__ mov(ip, Operand::Zero()); |
903 | 903 |
__ str(ip, MemOperand(r0, 3 * kPointerSize)); |
904 | 904 |
|
... | ... | |
916 | 916 |
masm->isolate()); |
917 | 917 |
|
918 | 918 |
AllowExternalCallThatCantCauseGC scope(masm); |
919 |
MemOperand context_restore_operand( |
|
920 |
fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
|
921 |
MemOperand return_value_operand(fp, |
|
922 |
(2 + FCA::kReturnValueOffset) * kPointerSize); |
|
923 |
|
|
919 | 924 |
__ CallApiFunctionAndReturn(ref, |
920 | 925 |
function_address, |
921 | 926 |
thunk_ref, |
922 | 927 |
r1, |
923 | 928 |
kStackUnwindSpace, |
924 |
kFastApiCallArguments + 1); |
|
929 |
return_value_operand, |
|
930 |
restore_context ? |
|
931 |
&context_restore_operand : NULL); |
|
925 | 932 |
} |
926 | 933 |
|
927 | 934 |
|
... | ... | |
935 | 942 |
ASSERT(optimization.is_simple_api_call()); |
936 | 943 |
ASSERT(!receiver.is(scratch)); |
937 | 944 |
|
945 |
typedef FunctionCallbackArguments FCA; |
|
938 | 946 |
const int stack_space = kFastApiCallArguments + argc + 1; |
939 | 947 |
// Assign stack space for the call arguments. |
940 | 948 |
__ sub(sp, sp, Operand(stack_space * kPointerSize)); |
941 | 949 |
// Write holder to stack frame. |
942 |
__ str(receiver, MemOperand(sp, 0));
|
|
950 |
__ str(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
|
|
943 | 951 |
// Write receiver to stack frame. |
944 | 952 |
int index = stack_space - 1; |
945 | 953 |
__ str(receiver, MemOperand(sp, index * kPointerSize)); |
... | ... | |
950 | 958 |
__ str(receiver, MemOperand(sp, index-- * kPointerSize)); |
951 | 959 |
} |
952 | 960 |
|
953 |
GenerateFastApiDirectCall(masm, optimization, argc); |
|
961 |
GenerateFastApiDirectCall(masm, optimization, argc, true);
|
|
954 | 962 |
} |
955 | 963 |
|
956 | 964 |
|
... | ... | |
1064 | 1072 |
|
1065 | 1073 |
// Invoke function. |
1066 | 1074 |
if (can_do_fast_api_call) { |
1067 |
GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); |
|
1075 |
GenerateFastApiDirectCall( |
|
1076 |
masm, optimization, arguments_.immediate(), false); |
|
1068 | 1077 |
} else { |
1069 | 1078 |
CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
1070 | 1079 |
? CALL_AS_FUNCTION |
... | ... | |
1202 | 1211 |
Register reg = object_reg; |
1203 | 1212 |
int depth = 0; |
1204 | 1213 |
|
1214 |
typedef FunctionCallbackArguments FCA; |
|
1205 | 1215 |
if (save_at_depth == depth) { |
1206 |
__ str(reg, MemOperand(sp)); |
|
1216 |
__ str(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
|
|
1207 | 1217 |
} |
1208 | 1218 |
|
1209 | 1219 |
// Check the maps in the prototype chain. |
... | ... | |
1262 | 1272 |
} |
1263 | 1273 |
|
1264 | 1274 |
if (save_at_depth == depth) { |
1265 |
__ str(reg, MemOperand(sp)); |
|
1275 |
__ str(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
|
|
1266 | 1276 |
} |
1267 | 1277 |
|
1268 | 1278 |
// Go to the next object in the prototype chain. |
... | ... | |
1294 | 1304 |
} |
1295 | 1305 |
|
1296 | 1306 |
|
1297 |
void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
|
|
1298 |
Label* success,
|
|
1299 |
Label* miss) {
|
|
1307 |
void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, |
|
1308 |
Label* success, |
|
1309 |
Label* miss) { |
|
1300 | 1310 |
if (!miss->is_unused()) { |
1301 | 1311 |
__ b(success); |
1302 | 1312 |
__ bind(miss); |
... | ... | |
1305 | 1315 |
} |
1306 | 1316 |
|
1307 | 1317 |
|
1308 |
void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
|
|
1309 |
Label* success,
|
|
1310 |
Label* miss) {
|
|
1318 |
void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, |
|
1319 |
Label* success, |
|
1320 |
Label* miss) { |
|
1311 | 1321 |
if (!miss->is_unused()) { |
1312 | 1322 |
__ b(success); |
1313 | 1323 |
GenerateRestoreName(masm(), miss, name); |
... | ... | |
1316 | 1326 |
} |
1317 | 1327 |
|
1318 | 1328 |
|
1319 |
Register BaseLoadStubCompiler::CallbackHandlerFrontend(
|
|
1329 |
Register LoadStubCompiler::CallbackHandlerFrontend( |
|
1320 | 1330 |
Handle<JSObject> object, |
1321 | 1331 |
Register object_reg, |
1322 | 1332 |
Handle<JSObject> holder, |
... | ... | |
1363 | 1373 |
} |
1364 | 1374 |
|
1365 | 1375 |
|
1366 |
void BaseLoadStubCompiler::NonexistentHandlerFrontend(
|
|
1376 |
void LoadStubCompiler::NonexistentHandlerFrontend( |
|
1367 | 1377 |
Handle<JSObject> object, |
1368 | 1378 |
Handle<JSObject> last, |
1369 | 1379 |
Handle<Name> name, |
... | ... | |
1383 | 1393 |
} |
1384 | 1394 |
|
1385 | 1395 |
|
1386 |
void BaseLoadStubCompiler::GenerateLoadField(Register reg,
|
|
1387 |
Handle<JSObject> holder,
|
|
1388 |
PropertyIndex field,
|
|
1389 |
Representation representation) {
|
|
1396 |
void LoadStubCompiler::GenerateLoadField(Register reg, |
|
1397 |
Handle<JSObject> holder, |
|
1398 |
PropertyIndex field, |
|
1399 |
Representation representation) { |
|
1390 | 1400 |
if (!reg.is(receiver())) __ mov(receiver(), reg); |
1391 | 1401 |
if (kind() == Code::LOAD_IC) { |
1392 | 1402 |
LoadFieldStub stub(field.is_inobject(holder), |
... | ... | |
1402 | 1412 |
} |
1403 | 1413 |
|
1404 | 1414 |
|
1405 |
void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
|
|
1415 |
void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { |
|
1406 | 1416 |
// Return the constant value. |
1407 |
__ LoadObject(r0, value);
|
|
1417 |
__ Move(r0, value);
|
|
1408 | 1418 |
__ Ret(); |
1409 | 1419 |
} |
1410 | 1420 |
|
1411 | 1421 |
|
1412 |
void BaseLoadStubCompiler::GenerateLoadCallback(
|
|
1422 |
void LoadStubCompiler::GenerateLoadCallback( |
|
1413 | 1423 |
const CallOptimization& call_optimization) { |
1414 | 1424 |
GenerateFastApiCall( |
1415 | 1425 |
masm(), call_optimization, receiver(), scratch3(), 0, NULL); |
1416 | 1426 |
} |
1417 | 1427 |
|
1418 | 1428 |
|
1419 |
void BaseLoadStubCompiler::GenerateLoadCallback(
|
|
1429 |
void LoadStubCompiler::GenerateLoadCallback( |
|
1420 | 1430 |
Register reg, |
1421 | 1431 |
Handle<ExecutableAccessorInfo> callback) { |
1422 | 1432 |
// Build AccessorInfo::args_ list on the stack and push property name below |
1423 | 1433 |
// the exit frame to make GC aware of them and store pointers to them. |
1424 |
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0); |
|
1425 |
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1); |
|
1426 |
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2); |
|
1427 |
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3); |
|
1428 |
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4); |
|
1429 |
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5); |
|
1434 |
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); |
|
1435 |
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); |
|
1436 |
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); |
|
1437 |
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); |
|
1438 |
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); |
|
1439 |
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); |
|
1440 |
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); |
|
1430 | 1441 |
ASSERT(!scratch2().is(reg)); |
1431 | 1442 |
ASSERT(!scratch3().is(reg)); |
1432 | 1443 |
ASSERT(!scratch4().is(reg)); |
1433 | 1444 |
__ push(receiver()); |
1434 |
__ mov(scratch2(), sp); // scratch2 = AccessorInfo::args_ |
|
1435 | 1445 |
if (heap()->InNewSpace(callback->data())) { |
1436 | 1446 |
__ Move(scratch3(), callback); |
1437 | 1447 |
__ ldr(scratch3(), FieldMemOperand(scratch3(), |
... | ... | |
1445 | 1455 |
__ Push(scratch3(), scratch4()); |
1446 | 1456 |
__ mov(scratch4(), |
1447 | 1457 |
Operand(ExternalReference::isolate_address(isolate()))); |
1448 |
__ Push(scratch4(), reg, name()); |
|
1458 |
__ Push(scratch4(), reg); |
|
1459 |
__ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_ |
|
1460 |
__ push(name()); |
|
1449 | 1461 |
__ mov(r0, sp); // r0 = Handle<Name> |
1450 | 1462 |
|
1451 | 1463 |
const int kApiStackSpace = 1; |
1452 | 1464 |
FrameScope frame_scope(masm(), StackFrame::MANUAL); |
1453 | 1465 |
__ EnterExitFrame(false, kApiStackSpace); |
1454 | 1466 |
|
1455 |
// Create AccessorInfo instance on the stack above the exit frame with |
|
1467 |
// Create PropertyAccessorInfo instance on the stack above the exit frame with
|
|
1456 | 1468 |
// scratch2 (internal::Object** args_) as the data. |
1457 | 1469 |
__ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); |
1458 | 1470 |
__ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& |
1459 | 1471 |
|
1460 |
const int kStackUnwindSpace = kFastApiCallArguments + 1;
|
|
1472 |
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
|
|
1461 | 1473 |
Address getter_address = v8::ToCData<Address>(callback->getter()); |
1462 | 1474 |
|
1463 | 1475 |
ApiFunction fun(getter_address); |
... | ... | |
1475 | 1487 |
thunk_ref, |
1476 | 1488 |
r2, |
1477 | 1489 |
kStackUnwindSpace, |
1478 |
6); |
|
1490 |
MemOperand(fp, 6 * kPointerSize), |
|
1491 |
NULL); |
|
1479 | 1492 |
} |
1480 | 1493 |
|
1481 | 1494 |
|
1482 |
void BaseLoadStubCompiler::GenerateLoadInterceptor(
|
|
1495 |
void LoadStubCompiler::GenerateLoadInterceptor( |
|
1483 | 1496 |
Register holder_reg, |
1484 | 1497 |
Handle<JSObject> object, |
1485 | 1498 |
Handle<JSObject> interceptor_holder, |
... | ... | |
1839 | 1852 |
|
1840 | 1853 |
if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { |
1841 | 1854 |
Label fast_object, not_fast_object; |
1842 |
__ CheckFastObjectElements(r3, r7, ¬_fast_object);
|
|
1855 |
__ CheckFastObjectElements(r3, r9, ¬_fast_object);
|
|
1843 | 1856 |
__ jmp(&fast_object); |
1844 | 1857 |
// In case of fast smi-only, convert to fast object, otherwise bail out. |
1845 | 1858 |
__ bind(¬_fast_object); |
1846 |
__ CheckFastSmiElements(r3, r7, &call_builtin);
|
|
1859 |
__ CheckFastSmiElements(r3, r9, &call_builtin);
|
|
1847 | 1860 |
|
1848 |
__ ldr(r7, FieldMemOperand(r4, HeapObject::kMapOffset));
|
|
1861 |
__ ldr(r9, FieldMemOperand(r4, HeapObject::kMapOffset));
|
|
1849 | 1862 |
__ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
1850 |
__ cmp(r7, ip);
|
|
1863 |
__ cmp(r9, ip);
|
|
1851 | 1864 |
__ b(eq, &call_builtin); |
1852 | 1865 |
// edx: receiver |
1853 | 1866 |
// r3: map |
... | ... | |
1855 | 1868 |
__ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, |
1856 | 1869 |
FAST_ELEMENTS, |
1857 | 1870 |
r3, |
1858 |
r7,
|
|
1871 |
r9,
|
|
1859 | 1872 |
&try_holey_map); |
1860 | 1873 |
__ mov(r2, receiver); |
1861 | 1874 |
ElementsTransitionGenerator:: |
... | ... | |
1868 | 1881 |
__ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS, |
1869 | 1882 |
FAST_HOLEY_ELEMENTS, |
1870 | 1883 |
r3, |
1871 |
r7,
|
|
1884 |
r9,
|
|
1872 | 1885 |
&call_builtin); |
1873 | 1886 |
__ mov(r2, receiver); |
1874 | 1887 |
ElementsTransitionGenerator:: |
... | ... | |
1901 | 1914 |
|
1902 | 1915 |
__ bind(&attempt_to_grow_elements); |
1903 | 1916 |
// r0: array's length + 1. |
1904 |
// r4: elements' length. |
|
1905 | 1917 |
|
1906 | 1918 |
if (!FLAG_inline_new) { |
1907 | 1919 |
__ b(&call_builtin); |
... | ... | |
1912 | 1924 |
// the new element is non-Smi. For now, delegate to the builtin. |
1913 | 1925 |
Label no_fast_elements_check; |
1914 | 1926 |
__ JumpIfSmi(r2, &no_fast_elements_check); |
1915 |
__ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
|
1916 |
__ CheckFastObjectElements(r7, r7, &call_builtin);
|
|
1927 |
__ ldr(r9, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
|
1928 |
__ CheckFastObjectElements(r9, r9, &call_builtin);
|
|
1917 | 1929 |
__ bind(&no_fast_elements_check); |
1918 | 1930 |
|
1919 | 1931 |
ExternalReference new_space_allocation_top = |
... | ... | |
1925 | 1937 |
// Load top and check if it is the end of elements. |
1926 | 1938 |
__ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0)); |
1927 | 1939 |
__ add(end_elements, end_elements, Operand(kEndElementsOffset)); |
1928 |
__ mov(r7, Operand(new_space_allocation_top));
|
|
1929 |
__ ldr(r3, MemOperand(r7));
|
|
1940 |
__ mov(r4, Operand(new_space_allocation_top));
|
|
1941 |
__ ldr(r3, MemOperand(r4));
|
|
1930 | 1942 |
__ cmp(end_elements, r3); |
1931 | 1943 |
__ b(ne, &call_builtin); |
1932 | 1944 |
|
... | ... | |
1938 | 1950 |
|
1939 | 1951 |
// We fit and could grow elements. |
1940 | 1952 |
// Update new_space_allocation_top. |
1941 |
__ str(r3, MemOperand(r7));
|
|
1953 |
__ str(r3, MemOperand(r4));
|
|
1942 | 1954 |
// Push the argument. |
1943 | 1955 |
__ str(r2, MemOperand(end_elements)); |
1944 | 1956 |
// Fill the rest with holes. |
... | ... | |
1949 | 1961 |
|
1950 | 1962 |
// Update elements' and array's sizes. |
1951 | 1963 |
__ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1964 |
__ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
|
1952 | 1965 |
__ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); |
1953 | 1966 |
__ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
1954 | 1967 |
|
... | ... | |
2539 | 2552 |
CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, name, |
2540 | 2553 |
depth, &miss); |
2541 | 2554 |
|
2542 |
GenerateFastApiDirectCall(masm(), optimization, argc); |
|
2555 |
GenerateFastApiDirectCall(masm(), optimization, argc, false);
|
|
2543 | 2556 |
|
2544 | 2557 |
__ bind(&miss); |
2545 | 2558 |
FreeSpaceForFastApiCall(masm()); |
... | ... | |
2991 | 3004 |
|
2992 | 3005 |
|
2993 | 3006 |
void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, |
3007 |
Register receiver, |
|
2994 | 3008 |
Handle<JSFunction> getter) { |
2995 | 3009 |
// ----------- S t a t e ------------- |
2996 | 3010 |
// -- r0 : receiver |
... | ... | |
3002 | 3016 |
|
3003 | 3017 |
if (!getter.is_null()) { |
3004 | 3018 |
// Call the JavaScript getter with the receiver on the stack. |
3005 |
__ push(r0);
|
|
3019 |
__ push(receiver);
|
|
3006 | 3020 |
ParameterCount actual(0); |
3007 | 3021 |
ParameterCount expected(getter); |
3008 | 3022 |
__ InvokeFunction(getter, expected, actual, |
Also available in: Unified diff