OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 4043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4054 } | 4054 } |
4055 | 4055 |
4056 | 4056 |
4057 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { | 4057 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
4058 Label invoke, handler_entry, exit; | 4058 Label invoke, handler_entry, exit; |
4059 Isolate* isolate = masm->isolate(); | 4059 Isolate* isolate = masm->isolate(); |
4060 | 4060 |
4061 // Registers: | 4061 // Registers: |
4062 // a0: entry address | 4062 // a0: entry address |
4063 // a1: function | 4063 // a1: function |
4064 // a2: reveiver | 4064 // a2: receiver |
4065 // a3: argc | 4065 // a3: argc |
4066 // | 4066 // |
4067 // Stack: | 4067 // Stack: |
4068 // 4 args slots | 4068 // 4 args slots |
4069 // args | 4069 // args |
4070 | 4070 |
4071 // Save callee saved registers on the stack. | 4071 // Save callee saved registers on the stack. |
4072 __ MultiPush(kCalleeSaved | ra.bit()); | 4072 __ MultiPush(kCalleeSaved | ra.bit()); |
4073 | 4073 |
4074 if (CpuFeatures::IsSupported(FPU)) { | 4074 if (CpuFeatures::IsSupported(FPU)) { |
(...skipping 21 matching lines...) Expand all Loading... |
4096 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, | 4096 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
4097 isolate))); | 4097 isolate))); |
4098 __ lw(t0, MemOperand(t0)); | 4098 __ lw(t0, MemOperand(t0)); |
4099 __ Push(t3, t2, t1, t0); | 4099 __ Push(t3, t2, t1, t0); |
4100 // Set up frame pointer for the frame to be pushed. | 4100 // Set up frame pointer for the frame to be pushed. |
4101 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset); | 4101 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset); |
4102 | 4102 |
4103 // Registers: | 4103 // Registers: |
4104 // a0: entry_address | 4104 // a0: entry_address |
4105 // a1: function | 4105 // a1: function |
4106 // a2: reveiver_pointer | 4106 // a2: receiver_pointer |
4107 // a3: argc | 4107 // a3: argc |
4108 // s0: argv | 4108 // s0: argv |
4109 // | 4109 // |
4110 // Stack: | 4110 // Stack: |
4111 // caller fp | | 4111 // caller fp | |
4112 // function slot | entry frame | 4112 // function slot | entry frame |
4113 // context slot | | 4113 // context slot | |
4114 // bad fp (0xff...f) | | 4114 // bad fp (0xff...f) | |
4115 // callee saved registers + ra | 4115 // callee saved registers + ra |
4116 // 4 args slots | 4116 // 4 args slots |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4163 isolate))); | 4163 isolate))); |
4164 __ sw(t1, MemOperand(t0)); | 4164 __ sw(t1, MemOperand(t0)); |
4165 | 4165 |
4166 // Invoke the function by calling through JS entry trampoline builtin. | 4166 // Invoke the function by calling through JS entry trampoline builtin. |
4167 // Notice that we cannot store a reference to the trampoline code directly in | 4167 // Notice that we cannot store a reference to the trampoline code directly in |
4168 // this stub, because runtime stubs are not traversed when doing GC. | 4168 // this stub, because runtime stubs are not traversed when doing GC. |
4169 | 4169 |
4170 // Registers: | 4170 // Registers: |
4171 // a0: entry_address | 4171 // a0: entry_address |
4172 // a1: function | 4172 // a1: function |
4173 // a2: reveiver_pointer | 4173 // a2: receiver_pointer |
4174 // a3: argc | 4174 // a3: argc |
4175 // s0: argv | 4175 // s0: argv |
4176 // | 4176 // |
4177 // Stack: | 4177 // Stack: |
4178 // handler frame | 4178 // handler frame |
4179 // entry frame | 4179 // entry frame |
4180 // callee saved registers + ra | 4180 // callee saved registers + ra |
4181 // 4 args slots | 4181 // 4 args slots |
4182 // args | 4182 // args |
4183 | 4183 |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4999 __ Branch(&external_string, ne, at, Operand(zero_reg)); | 4999 __ Branch(&external_string, ne, at, Operand(zero_reg)); |
5000 | 5000 |
5001 __ bind(&seq_string); | 5001 __ bind(&seq_string); |
5002 // subject: Subject string | 5002 // subject: Subject string |
5003 // regexp_data: RegExp data (FixedArray) | 5003 // regexp_data: RegExp data (FixedArray) |
5004 // a0: Instance type of subject string | 5004 // a0: Instance type of subject string |
5005 STATIC_ASSERT(kStringEncodingMask == 4); | 5005 STATIC_ASSERT(kStringEncodingMask == 4); |
5006 STATIC_ASSERT(kAsciiStringTag == 4); | 5006 STATIC_ASSERT(kAsciiStringTag == 4); |
5007 STATIC_ASSERT(kTwoByteStringTag == 0); | 5007 STATIC_ASSERT(kTwoByteStringTag == 0); |
5008 // Find the code object based on the assumptions above. | 5008 // Find the code object based on the assumptions above. |
5009 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ascii. | 5009 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ASCII. |
5010 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset)); | 5010 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset)); |
5011 __ sra(a3, a0, 2); // a3 is 1 for ascii, 0 for UC16 (usyed below). | 5011 __ sra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below). |
5012 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset)); | 5012 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset)); |
5013 __ movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset. | 5013 __ movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset. |
5014 | 5014 |
5015 // Check that the irregexp code has been generated for the actual string | 5015 // Check that the irregexp code has been generated for the actual string |
5016 // encoding. If it has, the field contains a code object otherwise it contains | 5016 // encoding. If it has, the field contains a code object otherwise it contains |
5017 // a smi (code flushing support). | 5017 // a smi (code flushing support). |
5018 __ JumpIfSmi(t9, &runtime); | 5018 __ JumpIfSmi(t9, &runtime); |
5019 | 5019 |
5020 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); | 5020 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); |
5021 // t9: code | 5021 // t9: code |
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6026 // Short-cut for the case of trivial substring. | 6026 // Short-cut for the case of trivial substring. |
6027 Label return_v0; | 6027 Label return_v0; |
6028 // v0: original string | 6028 // v0: original string |
6029 // a2: result string length | 6029 // a2: result string length |
6030 __ lw(t0, FieldMemOperand(v0, String::kLengthOffset)); | 6030 __ lw(t0, FieldMemOperand(v0, String::kLengthOffset)); |
6031 __ sra(t0, t0, 1); | 6031 __ sra(t0, t0, 1); |
6032 __ Branch(&return_v0, eq, a2, Operand(t0)); | 6032 __ Branch(&return_v0, eq, a2, Operand(t0)); |
6033 | 6033 |
6034 | 6034 |
6035 Label result_longer_than_two; | 6035 Label result_longer_than_two; |
6036 // Check for special case of two character ascii string, in which case | 6036 // Check for special case of two character ASCII string, in which case |
6037 // we do a lookup in the symbol table first. | 6037 // we do a lookup in the symbol table first. |
6038 __ li(t0, 2); | 6038 __ li(t0, 2); |
6039 __ Branch(&result_longer_than_two, gt, a2, Operand(t0)); | 6039 __ Branch(&result_longer_than_two, gt, a2, Operand(t0)); |
6040 __ Branch(&runtime, lt, a2, Operand(t0)); | 6040 __ Branch(&runtime, lt, a2, Operand(t0)); |
6041 | 6041 |
6042 __ JumpIfInstanceTypeIsNotSequentialAscii(a1, a1, &runtime); | 6042 __ JumpIfInstanceTypeIsNotSequentialAscii(a1, a1, &runtime); |
6043 | 6043 |
6044 // Get the two characters forming the sub string. | 6044 // Get the two characters forming the sub string. |
6045 __ Addu(v0, v0, Operand(a3)); | 6045 __ Addu(v0, v0, Operand(a3)); |
6046 __ lbu(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); | 6046 __ lbu(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6157 // Locate first character of underlying subject string. | 6157 // Locate first character of underlying subject string. |
6158 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); | 6158 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
6159 __ Addu(t1, t1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 6159 __ Addu(t1, t1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
6160 | 6160 |
6161 __ bind(&allocate_result); | 6161 __ bind(&allocate_result); |
6162 // Sequential acii string. Allocate the result. | 6162 // Sequential acii string. Allocate the result. |
6163 STATIC_ASSERT((kAsciiStringTag & kStringEncodingMask) != 0); | 6163 STATIC_ASSERT((kAsciiStringTag & kStringEncodingMask) != 0); |
6164 __ And(t0, a1, Operand(kStringEncodingMask)); | 6164 __ And(t0, a1, Operand(kStringEncodingMask)); |
6165 __ Branch(&two_byte_sequential, eq, t0, Operand(zero_reg)); | 6165 __ Branch(&two_byte_sequential, eq, t0, Operand(zero_reg)); |
6166 | 6166 |
6167 // Allocate and copy the resulting ascii string. | 6167 // Allocate and copy the resulting ASCII string. |
6168 __ AllocateAsciiString(v0, a2, t0, t2, t3, &runtime); | 6168 __ AllocateAsciiString(v0, a2, t0, t2, t3, &runtime); |
6169 | 6169 |
6170 // Locate first character of substring to copy. | 6170 // Locate first character of substring to copy. |
6171 __ Addu(t1, t1, a3); | 6171 __ Addu(t1, t1, a3); |
6172 | 6172 |
6173 // Locate first character of result. | 6173 // Locate first character of result. |
6174 __ Addu(a1, v0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 6174 __ Addu(a1, v0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
6175 | 6175 |
6176 // v0: result string | 6176 // v0: result string |
6177 // a1: first character of result string | 6177 // a1: first character of result string |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6501 // If result is not supposed to be flat, allocate a cons string object. | 6501 // If result is not supposed to be flat, allocate a cons string object. |
6502 // If both strings are ASCII the result is an ASCII cons string. | 6502 // If both strings are ASCII the result is an ASCII cons string. |
6503 if (flags_ != NO_STRING_ADD_FLAGS) { | 6503 if (flags_ != NO_STRING_ADD_FLAGS) { |
6504 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); | 6504 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); |
6505 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); | 6505 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); |
6506 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); | 6506 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); |
6507 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); | 6507 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); |
6508 } | 6508 } |
6509 Label non_ascii, allocated, ascii_data; | 6509 Label non_ascii, allocated, ascii_data; |
6510 STATIC_ASSERT(kTwoByteStringTag == 0); | 6510 STATIC_ASSERT(kTwoByteStringTag == 0); |
6511 // Branch to non_ascii if either string-encoding field is zero (non-ascii). | 6511 // Branch to non_ascii if either string-encoding field is zero (non-ASCII). |
6512 __ And(t4, t0, Operand(t1)); | 6512 __ And(t4, t0, Operand(t1)); |
6513 __ And(t4, t4, Operand(kStringEncodingMask)); | 6513 __ And(t4, t4, Operand(kStringEncodingMask)); |
6514 __ Branch(&non_ascii, eq, t4, Operand(zero_reg)); | 6514 __ Branch(&non_ascii, eq, t4, Operand(zero_reg)); |
6515 | 6515 |
6516 // Allocate an ASCII cons string. | 6516 // Allocate an ASCII cons string. |
6517 __ bind(&ascii_data); | 6517 __ bind(&ascii_data); |
6518 __ AllocateAsciiConsString(v0, t2, t0, t1, &call_runtime); | 6518 __ AllocateAsciiConsString(v0, t2, t0, t1, &call_runtime); |
6519 __ bind(&allocated); | 6519 __ bind(&allocated); |
6520 // Fill the fields of the cons string. | 6520 // Fill the fields of the cons string. |
6521 __ sw(a0, FieldMemOperand(v0, ConsString::kFirstOffset)); | 6521 __ sw(a0, FieldMemOperand(v0, ConsString::kFirstOffset)); |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7581 __ Ret(USE_DELAY_SLOT); | 7581 __ Ret(USE_DELAY_SLOT); |
7582 __ mov(v0, a0); | 7582 __ mov(v0, a0); |
7583 } | 7583 } |
7584 | 7584 |
7585 | 7585 |
7586 #undef __ | 7586 #undef __ |
7587 | 7587 |
7588 } } // namespace v8::internal | 7588 } } // namespace v8::internal |
7589 | 7589 |
7590 #endif // V8_TARGET_ARCH_MIPS | 7590 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |